Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
bendertez
Yak Posting Veteran
94 Posts |
Posted - 2010-10-05 : 09:16:36
|
HiI have a table that contains read_values that I want to return the latest read along with the previous read.My table and some of the data contained in it looks like below:Act_Ref Read ReadID ReadDateBEG0022 4508 100011 20100901BEG0022 4556 100014 20100902BEG0022 4403 100010 20100801BEG0025 4598 100015 20100902BEG0025 4568 100306 20100905BEG0025 4500 100306 20100801BEG0123 4578 100012 20100901BEG0123 4590 100017 20100905BEG0456 4603 100018 20100905BEG0456 4544 100013 20100901I only want to return the last two reads by Act_Ref using the Read_ID field, so my outcome would look something like:Act_Ref Prev CurrBEG0022 4508 4556BEG0025 4568 4598BEG0123 4578 4590BEG0456 4544 4603I can produce a query to get the MAX read to produce the current read, but how would I choose the previous read as well?Any advice would be much appreciated.Thanks in advanceDave |
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2010-10-05 : 10:14:46
|
I think OUTER APPLY would be your friend here.Something likeDECLARE @foo TABLE ( [Act_ref] VARCHAR(255) , [Read] INT PRIMARY KEY , [readID] INT , [readDate] DATETIME )INSERT @foo SELECT 'BEG0022', 4508, 100011, '20100901'UNION SELECT 'BEG0022', 4556, 100014, '20100902'UNION SELECT 'BEG0022', 4403, 100010, '20100801'UNION SELECT 'BEG0025', 4598, 100015, '20100902'UNION SELECT 'BEG0025', 4568, 100306, '20100905'UNION SELECT 'BEG0025', 4500, 100306, '20100801'UNION SELECT 'BEG0123', 4578, 100012, '20100901'UNION SELECT 'BEG0123', 4590, 100017, '20100905'UNION SELECT 'BEG0456', 4603, 100018, '20100905'UNION SELECT 'BEG0456', 4544, 100013, '20100901'SELECT dt.[act_ref] AS [act_ref] , prev.[prev] AS [Prev] , cur.[cur] AS [Curr]FROM ( SELECT DISTINCT [act_ref] AS [act_ref] FROM @foo ) AS dt CROSS APPLY ( SELECT TOP 1 f.[read] AS [cur] , f.[readDate] AS [curDate] FROM @foo AS f WHERE f.[act_ref] = dt.[act_ref] ORDER BY f.[readDate] DESC ) AS cur OUTER APPLY ( SELECT TOP 1 f.[read] AS [prev] FROM @foo AS f WHERE f.[act_ref] = dt.[act_ref] AND f.[readDate] < cur.[curDate] ORDER BY f.[readDate] DESC ) AS prev NOTE -- you should normalise this table so that Act_ref is a foreign key to a action_ref table. Then you don't have to distinct anything. If you did you could replace the (SELECT DISTINCT....) derived table and the CROSS APPPLY with a simple, prefrmant GROUP BY or ROW_NUNBER() approach.Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
webfred
Master Smack Fu Yak Hacker
8781 Posts |
Posted - 2010-10-05 : 10:16:49
|
This should work:select Act_Ref, min(Read) as Prev, max(Read) as Currfrom(selectrow_number() over (partition by Act_ref order by Read DESC) as rownum,Act_Ref,Readfrom YourTable) as dtwhere rownum < 3group by Act_Ref No, you're never too old to Yak'n'Roll if you're too young to die. |
 |
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2010-10-05 : 10:19:45
|
Read is a keyword. you need to use square brackets round it.[code]select Act_Ref, min([Read]) as Prev, max([Read]) as Currfrom(selectrow_number() over (partition by Act_ref order by [Read] DESC) as rownum,Act_Ref,[Read]from @foo) as dtwhere rownum < 3group by Act_Ref Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
webfred
Master Smack Fu Yak Hacker
8781 Posts |
Posted - 2010-10-05 : 10:26:36
|
quote: Originally posted by Transact Charlie Read is a keyword. you need to use square brackets round it.[code]select Act_Ref, min([Read]) as Prev, max([Read]) as Currfrom(selectrow_number() over (partition by Act_ref order by [Read] DESC) as rownum,Act_Ref,[Read]from @foo) as dtwhere rownum < 3group by Act_Ref Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION
That's right - thank you. No, you're never too old to Yak'n'Roll if you're too young to die. |
 |
|
|
|
|
|
|