I want to achieve the below using SQL can anyone please help:
TOP BOTTOM Rocksymbol 0 5 l 5 10 l 10 15 ml 15 20 ml 20 25 ml 25 30 s 30 35 ml 35 40 ml 40 45 s
Should become:
TOP BOTTOM Rocksymbol 0 10 l 10 25 ml 25 30 s 30 40 ml 40 45 s
Basically wanting to group the data for same consecutive RockSymbol, where in the result the TOP of first record of the consecutive block becomes the TOP of the grouped record and the BOTTOM of last record of the consecutive block becomes the BOTTOM of the grouped record.
The number of consecutive RockSymbol records can vary.
Advertisement
Answer
Updated answer – considering situation where we can have multiple consecutive rows with same RockSymbol.
SELECT MIN([top]) as [top], MAX(bottom) as bottom, RockSymbol FROM ( SELECT ROW_NUMBER() OVER (ORDER BY [top]) rowid, ROW_NUMBER() OVER (PARTITION BY RockSymbol ORDER BY [top]) seqid ,* FROM [dbo].[tbl] ) tempt GROUP BY RockSymbol, rowid - seqid ORDER BY [top]
SQl fiddle link http://sqlfiddle.com/#!6/dc3c3/3
Edit: Old answer – only for the purpose of understanding the evolution of solution
If you can mutate original table then probably update statement
UPDATE A SET A.[TOP]=B.[TOP] FROM [dbo].[tbl] A INNER JOIN [dbo].[tbl] B ON A.[TOP]=B.BOTTOM AND A.RockSymbol=B.RockSymbolfollowed by removal of extra rows
DELETE FROM [dbo].[tbl] FROM [dbo].[tbl] B LEFT JOIN ( SELECT ROW_NUMBER() OVER(PARTITION BY [Top] ORDER BY Bottom DESC) AS "Rank", [TOP], BOTTOM, RockSymbol FROM [dbo].[tbl]) A ON A.[TOP]=B.[Top] AND A.[Bottom]=B.[Bottom] AND A.RockSymbol=B.RockSymbol WHERE A.Rank>1If you cannot update table please use a temp table or nested
SELECT
query like belowSELECT Q.[TOP], MAX(Q.BOTTOM) as BOTTOM,Q.RockSymbol FROM (SELECT ISNULL(B.[TOP],A.[TOP]) AS [TOP], A.BOTTOM, A.RockSymbol FROM [dbo].[tbl] A LEFT JOIN [dbo].[tbl] B ON A.[TOP]=B.BOTTOM AND A.RockSymbol=B.RockSymbol) Q GROUP BY Q.[TOP], Q.RockSymbolSql fiddles link for both solution are here http://sqlfiddle.com/#!6/e1148/1/0 and http://sqlfiddle.com/#!6/e1148/7