views:

156

answers:

2

alt text

In the above FldID 52 = Description and FldID 54 = HistoryDetail

alt text

For any given date the output should be the last entry for that date. Also the columns need to be become rows. User will provide 2 dates. Say March 2, 2010 and March 3, 2010.

So output in above case should be

alt text

Since Rev 6 does not have an entry for FldID 52 in Table A, [Placeholder 1] should have Words from Rev 3 (since that is the latest before Rev 6 for FldID 52 in Table A).

Similarly,
Since Rev 6 does not have an entry for FldID 54 in Table A, [Placeholder 2] should have Words from Rev 5 (since that is the latest before Rev 6 for FldID 54 in Table A).

Since Rev 8 does not have an entry for FldId 54 in Table A, [Placeholder 3] should have Words from Rev 7 (since that is the latest before Rev 8 for FldID 54 in Table A).

I am unable to come up with a query that can give me the above results. Please help.

update

Datatypes for fields in TABLE B

alt text

A: 
SELECT 
LAST(System.ChangedDate) as ChangedDate,
LAST(System.Rev) as Rev,
LAST(System.ChangedBy) as ChangedBy,
LAST(System.AssignedTO) AS AssignedTO,
LAST(System.IterationPath) AS IterationPath,
LAST(A1.Description) AS Description,
LAST(A2.Description) AS HistroyDetail
FROM TableB
JOIN TableA on TableB.Id=TableA.ID AND TableB.(datefunction)=TableA=(datefunction) 
AND FldID=52 AS A1
JOIN TableA on TableB.Id=TableA.ID AND TableB.(datefunction)=TableA=(datefunction) 
AND fldID=54 AS A2
WHERE (datefunction) >= (minimum date) and (datefunction) <= (minimum date);
ORDER BY ChangedDate
GROUP BY (datefunction)

Replace datefunction with the function that extracts the date and ignores the Time from the datetime field. This will give a table like what you want but 90 degree's off.

MindStalker
SQL Server doesn't have a `LAST` aggregate. Never did. Not that this would give the expected results even if it did.
Aaronaught
+1  A: 

This is basically a combination of a groupwise maximum query and a reverse pivot. The simple approach is to use ROW_NUMBER and UNPIVOT.

I'll show you how to do this for one date. To do two dates it's basically just copy and paste with a second date parameter and a join at the end on the FieldName column. You also haven't posted any description schema so I'm going to assume you have a table called FieldDescription that maps the FldID to its corresponding name (such as HistoryDetail).

;WITH A_CTE AS
(
    SELECT
        fd.FieldName, a.Words,
        ROW_NUMBER() OVER (PARTITION BY a.FldID ORDER BY a.Rev DESC) AS RowNum
    FROM TableA a
    INNER JOIN FieldDescription fd
        ON fd.FldID = a.FldID
    WHERE AddedDate <= @Date
),

B_CTE AS
(
    SELECT
        IterationPath,
        CAST(ChangedDate AS nvarchar(4000)) AS ChangedDate,
        CAST(Rev AS nvarchar(4000)) AS Rev,
        CAST(ChangedBy AS nvarchar(4000)) AS ChangedBy,
        CAST(AssignedTo AS nvarchar(4000)) AS AssignedTo,
        ROW_NUMBER() OVER
        (
            PARTITION BY Rev
            ORDER BY ChangedDate DESC
        ) AS RowNum
    FROM TableB
    WHERE ChangedDate <= @Date
),

Props AS
(
    SELECT PropertyName, PropertyValue
    FROM B_CTE
    UNPIVOT
    (
        PropertyValue
        FOR PropertyName IN
        (
            IterationPath, ChangedDate, Rev, ChangedBy, AssignedTo
        )
    ) AS u
    WHERE RowNum = 1
)

SELECT FieldName, Words
FROM A_CTE
WHERE RowNum = 1

UNION ALL

SELECT PropertyName, PropertyValue
FROM Props
Aaronaught
thanks aaronaught. When I parse the query it gives me "incorrect syntax near the keyword WHERE". Its the WHERE RowNum = 1 statement from the Props CTE. Pls. suggest.
stackoverflowuser
@stackoverflowuser: Sorry, you need to name the `UNPIVOT` subquery. Check edit, where I added `AS u`.
Aaronaught
thanks. there is another error that is coming up. "The type of column "ChangedDate" conflicts with the type of other columns specified in the UNPIVOT list." Pls. suggest
stackoverflowuser
I tried to convert the ChangedDate to varchar using CONVERT function. That does not seem to help. Pls. suggest.
stackoverflowuser
@stackoverflowuser: You need to convert before the `UNPIVOT` query. I've updated the example to do this in the CTE.
Aaronaught
I tried it but the error is still coming up. Also when i remove the changeddate from the unpivot list it starts giving error for Rev field. I keep removing the fields one by one and the error goes when only one field is left.I have edited the question and included the data types for each of the fields. Please let me know what needs to be done to get rid of the error. Thanks
stackoverflowuser
I changed all fields in the CTE to cast to exactly the same type.
Aaronaught
thanks aaronaught. that worked. I am still new to concepts of CTE and unpivot. Unable to comprehend how to make this work for 2 dates. I am planning to write a stored procedure which will accept 2 dates. The above query gives me output for 1 date. How can i join the output of another date with the earlier date and present it in the format I have shown in the output image in my question. Pls. help.
stackoverflowuser
@stackoverflowuser: You just duplicate every CTE but use a different date parameter, say `@BeginDate` and `@EndDate` instead of just one with `@Date`. Then you `INNER JOIN` the first set of CTEs on `FieldName` and the second set on `PropertyName`.
Aaronaught