基于“翻转”列运行“分组依据”序数计数器

时间:2015-04-27 01:59:22

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

通常我在基于集合的tsql问题上很不错。但这一次打败了我。 我已经工作了3天,将while循环程序转换为基于set的程序。我已经到了以下这一点.......但是不能进行最后的跳跃。

我有以下几行。 MyOrdinal将“按顺序”...并且第二列(MyMarker)将在具有值和为空之间交替。每当MyMarker发生这种“翻转”时,我想将“分组依据”序数递增一。只要“翻转”值为非null或null,就会将它们组合在一起作为一个集合。

我尝试了几件事,但是发帖太难看了。自从转移到ORM以来,我不再在tsql中花费太多时间了。

declare @Holder table (   MyOrdinal int not null , MyMarker int , MyGroupNumber int   )

INSERT INTO @Holder (MyOrdinal, MyMarker)
Select 1 , 1 
union all Select 2, 2
union all Select 3, null
union all Select 4, 3
union all Select 5, 4
union all Select 6, 5
union all Select 7, 6
union all Select 8, 7
union all Select 9, 8
union all Select 10, 9
union all Select 11, 10
union all Select 12, 11
union all Select 13, 12
union all Select 14, 13
union all Select 15, 14
union all Select 16, 15
union all Select 17, null
union all Select 18, null
union all Select 19, null
union all Select 20, 16
union all Select 21, 17
union all Select 22, 18
union all Select 23, null
union all Select 24, null
union all Select 25, 19
union all Select 26, 20
union all Select 27, null
union all Select 28, 21

Select * from @Holder

期望输出

| MyOrdinal | MyMarker | MyGroupNumber |
|-----------|----------|---------------|
|         1 |        1 |             1 |
|         2 |        2 |             1 |
|         3 |    null  |             2 |
|         4 |        3 |             3 |
|         5 |        4 |             3 |
|         6 |        5 |             3 |
|         7 |        6 |             3 |
|         8 |        7 |             3 |
|         9 |        8 |             3 |
|        10 |        9 |             3 |
|        11 |       10 |             3 |
|        12 |       11 |             3 |
|        13 |       12 |             3 |
|        14 |       13 |             3 |
|        15 |       14 |             3 |
|        16 |       15 |             3 |
|        17 |    null  |             4 |
|        18 |    null  |             4 |
|        19 |    null  |             4 |
|        20 |       16 |             5 |
|        21 |       17 |             5 |
|        22 |       18 |             5 |
|        23 |    null  |             6 |
|        24 |    null  |             6 |
|        25 |       19 |             7 |
|        26 |       20 |             7 |
|        27 |    null  |             8 |
|        28 |       21 |             9 |

2 个答案:

答案 0 :(得分:3)

试试这个:

首先,这为连续的非ROW_NUMBER NULL分配了相同的MyMarkerROW_NUMBER NULL的{​​{1}}为NULL。之后,您要为MyMarker ROW_NUMBER添加NULL,使其值介于之前的NON - MyMarker和下一个NON - NULL之间。然后使用NULL最终分配DENSE_RANK

SQL Fiddle

MyGroupNumber

答案 1 :(得分:2)

Sql Server 2012

select *, sum(b) over(order by myordinal) 
from(select *,  
            case when (lag(mymarker) over(order by myordinal) is not null 
                   and mymarker is null) or 
                   (lag(mymarker) over(order by myordinal) is null 
                   and mymarker is not null)
            then 1 else 0 end as b
from @Holder) t

首先,您将行标记为1,其中nullnot nullnot nullnull之间有变化。其他列标记为0.然后运行所有行的总和直到当前。 小提琴http://sqlfiddle.com/#!6/9eecb/5015

对于Sql Server 2008:

with cte1 as (select *,
case when (select max(enddate) from t ti
           where ti.ruleid = t.ruleid and ti.startdate < t.startdate) = startdate 
           then 0 else 1 end as b
from t),
cte2 as(select *, sum(b) over(partition by ruleid order by startdate) as s
from cte1)
select RuleID, 
       Name, 
       min(startdate), 
       case when count(*) = count(enddate) 
            then max(enddate) else null end from cte2
group by s, ruleid, name

小提琴http://sqlfiddle.com/#!6/4191d/6