问题
I have a simple 2 column table. PctGain contains weekly percentage stock market gains. WSeqkey contains a contiguous integer value that increments each new week. There are approximately 3300 rows in the above table. Here is a sample.
PctGain WSeqKey
0.12% 4407
0.31% 4406
0.68% 4405
1.14% 4404
0.95% 4403
0.38% 4402
4.57% 4401
-1.94% 4400
1.17% 4399
-0.32% 4398
What would like help solving, and learning how to do along the way is...write/run a query that will tell me when the positive and negative sequences begin and end. Something like
Negative Beg 4398
Negative End 4398
Positive Beg 4399
Positive End 4399
Negative Beg 4400
Negative End 4400
Positive Beg 4401
Positive End 4407
Thank you in advance for solving this and helping me learn along the way.
Frank
回答1:
Something like this should do the job SQL Fiddle
It finds islands of sequential data with the same value for SIGN
and alllocates them the same grouping value using Itzik Ben Gan's row number technique then groups them and aggregates them. The CROSS APPLY ... VALUES
unpivots the MIN
and MAX
;WITH T1
AS (SELECT *,
ROW_NUMBER() OVER (PARTITION BY SIGN(PctGain)
ORDER BY WSeqKey) - WSeqKey AS Grp
FROM YourTable),
T2
AS (SELECT MIN(WSeqKey) AS BeginSeq,
MAX(WSeqKey) AS EndSeq,
SIGN(PctGain) AS Sign
FROM T1
GROUP BY Grp,
SIGN(PctGain))
SELECT CASE Sign
WHEN -1 THEN 'Negative'
WHEN 0 THEN 'Equal'
WHEN 1 THEN 'Positive'
END AS [Sign],
Descriptor,
SeqKey
FROM T2
CROSS APPLY (VALUES('Begin', BeginSeq),
('End', EndSeq)) V(Descriptor, SeqKey)
ORDER BY SeqKey
回答2:
Thanks everyone I looked at the gaps/islands URL on MSDN and figured it out.
I dumped just the WSEQKEYs into a temp table (#gaps) while filtering on pctgain > 0 and then used the following sql:
SELECT t1.gapID as startOfGroup, MIN(t2.gapID)
as endOfGroup FROM (SELECT gapID FROM #gaps tbl1
WHERE NOT EXISTS(SELECT * FROM #gaps tbl2
WHERE tbl1.gapID - tbl2.gapID = 1)) t1
INNER JOIN (SELECT gapID FROM #gaps tbl1
WHERE NOT EXISTS(SELECT * FROM #gaps tbl2
WHERE tbl2.gapID - tbl1.gapID = 1)) t2
ON t1.gapID <= t2.gapID GROUP BY t1.gapID
order by t1.gapID desc
来源:https://stackoverflow.com/questions/14927466/sql-server-2008-r2-islands-and-gaps