我需要使用可怕的sql server loop / cursor来获取我需要的结果集吗?

时间:2012-09-08 00:06:08

标签: sql-server sql-server-2008 tsql sql-server-2008-r2

我需要一个在列值上“中断”的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的分区或排序将无法对日期列进行排序。我希望这是有道理的。我拼了命要做到这一点没有游标的情况,但我不能让它提前上班..谢谢。

1 个答案:

答案 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