我需要一个在列值上“中断”的sql server结果集,但是如果我在排序函数中按此列排序,那么我真正需要的顺序就会丢失。最好用例子来解释。我正在尝试的查询是:
select RANK() over(partition by Symbol, Period order by TradeDate desc)
SymbSmaOverUnderGroup, Symbol, TradeDate, Period, Value, Low, LowMinusVal,
LMVSign
from #smasAndLow3
然后它返回:
Rnk Symbol TradeDate Period Value Low LowMinusVal LMVSign
1 A 9/6/12 5 37.09 36.71 -.38 U
2 A 9/5/12 5 37.03 36.62 -.41 U
3 A 9/4/12 5 37.07 36.71 -.36 U
4 A 8/31/12 5 37.15 37.30 .15 O
5 A 8/30/12 5 37.22 37.40 .18 O
6 A 8/29/12 5 37.00 36.00 -1.00 U
7 A 8/28/12 5 37.10 37.00 -.10 U
我需要的排名是:1,1,1,2,2,3,3
。因此我需要按Symbol,Period进行分区,我需要在LMVSign上启动一个新分区(它只包含值U,O和E),但是我必须通过TradeDate desc进行排序。除非我弄错了,LMVSign的分区或排序将无法对日期列进行排序。我希望这是有道理的。我拼了命要做到这一点没有游标的情况,但我不能让它提前上班..谢谢。
答案 0 :(得分:5)
更新:我认为您正在进入岛屿和差距的世界。如果您的要求是按行,按期间和LMVSign对行进行分组,请按照TradeDate的顺序排序,在这些列中的任何一列发生更改时对它们进行排名,您可以使用它(by Itzik Ben-Gan's solution to islands and gaps)。
; with islandsAndGaps as
(
select *,
-- Create groups. Important part is order by
-- The difference remains the same as two sequences
-- run along, but the number itself is not ordered
row_number() over (partition by Symbol, Period
order by TradeDate)
- row_number() over (partition by Symbol, Period
order by LMVSign, TradeDate) grp
from Table1
),
grouped as
(
select *,
-- So to order it we use last date in group
-- (mind partition by uses changed order by from second row_number
-- and unordered group number
max(TradeDate) over(partition by LMVSign, grp) DateGroup
from islandsAndGaps
)
-- now we can get rank
select dense_rank() over (order by DateGroup desc) Rnk,
*
from grouped
order by TradeDate desc
<强> Take a look at Sql Fiddle 强>
OLD回答:
重新启动排名分区。我认为您需要订购:
dense_rank() over (order by Symbol, Period, LMVSign desc) Rnk
然后你应该按顺序使用TradeDate:
order by Rnk, TradeDate desc
如果您需要它作为数字,请添加另一列:
row_number() over (order by Symbol, Period, LMVSign desc, TradeDate desc) rn