通常我在基于集合的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 |
答案 0 :(得分:3)
试试这个:
首先,这为连续的非ROW_NUMBER
NULL
分配了相同的MyMarker
。 ROW_NUMBER
NULL
的{{1}}为NULL
。之后,您要为MyMarker
ROW_NUMBER
添加NULL
,使其值介于之前的NON - MyMarker
和下一个NON - NULL
之间。然后使用NULL
最终分配DENSE_RANK
:
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,其中null
到not null
或not null
到null
之间有变化。其他列标记为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