2

我有一个简单的 2 列表。PctGain 包含每周百分比的股市收益。WSeqkey 包含一个连续的整数值,每个新的一周递增。上表中大约有 3300 行。这是一个示例。

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

想要帮助解决并学习如何做的是......编写/运行一个查询,它将告诉我正负序列何时开始和结束。就像是

Negative Beg 4398
Negative End 4398
Positive Beg 4399
Positive End 4399
Negative Beg 4400
Negative End 4400
Positive Beg 4401
Positive End 4407

提前感谢您解决此问题并帮助我一路学习。

坦率

4

2 回答 2

2

像这样的东西应该可以完成SQL Fiddle的工作

SIGN它使用 Itzik Ben Gan 的行号技术找到具有相同值的顺序数据岛,并为它们分配相同的分组值,然后对它们进行分组和聚合。CROSS APPLY ... VALUESunpivotsMIN和_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 
于 2013-02-17T23:59:05.847 回答
1

谢谢大家,我查看了 MSDN 上的 gaps/islands URL 并弄清楚了。

我在过滤 pctgain > 0 时只将 WSEQKEY 转储到临时表 (#gaps) 中,然后使用以下 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
于 2013-02-18T02:57:09.837 回答