I’m attempting to write a query that will return
- The most recent AccountDate with a record of 0 per locationID
- Then the second most recent AccountDate per locationID. The record can be either 1 or 0.
- If there are two AccountDates with the same date then return the most recent AccountDate based on DateAccountLoaded
How ever my solution doesn’t look very elegant. Has anyone got a better way of achieving this.
Please see below my solution
CREATE TABLE [dbo].[TopTwoKeyed](
ID INT IDENTITY(1,1) PRIMARY KEY(ID),
[LocationID] [int] NULL,
[AccountDate] [date] NULL,
[Record] [tinyint] NULL,
[DateAccountLoaded] [date] NULL
)
INSERT INTO [dbo].[TopTwoKeyed] (
[LocationID],
AccountDate,
Record,
DateAccountLoaded
)
VALUES(1,'2009-10-31',0,'2011-03-23'),
(1,'2008-10-31',1,'2011-03-23'),
(1,'2008-10-31',0,'2010-03-22'),
(1,'2008-10-31',1,'2009-03-23'),
(1,'2011-10-31',1,'2010-03-22'),
(1,'2009-10-31',0,'2010-03-23'),
(2,'2011-10-31',0,'2010-03-23'),
(2,'2010-10-31',0,'2010-03-23'),
(2,'2010-10-31',1,'2010-03-23'),
(2,'2010-10-31',1,'2009-03-23'),
(3,'2010-10-31',0,'2010-03-23'),
(3,'2009-10-31',0,'2010-03-23'),
(3,'2008-10-31',1,'2010-03-23')
-- Get the most recent Account Date per locationID which has a record type of 0
SELECT f.LocationID
,f.AccountDate
,f.DateAccountLoaded
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY LocationID ORDER BY AccountDate DESC,DateAccountLoaded DESC) AS RowNumber
,LocationID AS LocationID
,AccountDate AS AccountDate
,DateAccountLoaded AS DateAccountLoaded
FROM [dbo].[TopTwoKeyed]
WHERE Record = 0
) f
WHERE f.RowNumber = 1
UNION ALL
SELECT ff.LocationID
,ff.AccountDate
,ff.DateAccountLoaded
FROM (
-- Get the SECOND most recent AccountDate. Can be either Record 0 or 1.
SELECT ROW_NUMBER() OVER (PARTITION BY LocationID ORDER BY AccountDate DESC,DateAccountLoaded DESC) AS RowNumber
,LocationID AS LocationID
,AccountDate AS AccountDate
,DateAccountLoaded 'DateAccountLoaded'
FROM [dbo].[TopTwoKeyed] tt
WHERE EXISTS
(
-- Same query as top of UNION. Get the most recent Account Date per locationID which has a record type of 0
SELECT 1
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY LocationID ORDER BY AccountDate DESC,DateAccountLoaded DESC) AS RowNumber
,LocationID AS LocationID
,AccountDate AS AccountDate
FROM [dbo].[TopTwoKeyed]
WHERE Record = 0
) f
WHERE f.RowNumber = 1
AND tt.LocationID = f.LocationID
AND tt.AccountDate < f.AccountDate
)
) ff
WHERE ff.RowNumber = 1
-- DROP TABLE [dbo].[TopTwoKeyed]
You could use a
row_numbersubquery to find the most recent account date. Then you canouter applyto search for the next most recent account date:EDIT: To place the rows below eachother, you probably have to use a
union. A singlerow_numbercan’t work because the second row has different criterium for theRecordcolumn.