请参阅小提琴:http://sqlfiddle.com/#!6/e6768/2
我有数据,如下所示:
DRIVER DROP
1 1
1 2
1 ReturnToBase
1 4
1 5
1 ReturnToBase
1 6
1 7
2 1
2 2
2 ReturnToBase
2 4
我正在尝试对数据进行分组,因此对于每个驱动程序,每组返回基数都有一个分组编号。
我的输出应如下所示:
DRIVER DROP GROUP
1 1 1
1 2 1
1 ReturnToBase 1
1 4 2
1 5 2
1 ReturnToBase 2
1 6 3
1 7 3
1 ReturnToBase 3
2 1 1
2 2 1
2 ReturnToBase 1
2 4 2
我尝试使用窗口函数的组合来获得此结果,但到目前为止,我已经离开了里程
以下是我到目前为止所做的事情,它不应该起作用我试图弄清楚它是如何完成的,如果它可能的话。
SELECT
ROW_NUMBER() OVER (Partition BY Driver order by Driver Desc) rownum,
Count(1) OVER (Partition By Driver Order By Driver Desc) counter,
Count
DropNo,
Driver,
CASE DropNo
WHEN 'ReturnToBase' THEN 1 ELSE 0 END AS EnumerateRound
FROM
Rounds
答案 0 :(得分:5)
您可以使用以下查询:
SELECT id, DRIVER, DROPno,
1 + SUM(flag) OVER (PARTITION BY DRIVER ORDER BY id) -
CASE
WHEN DROPno = 'ReturnToBase' THEN 1
ELSE 0
END AS grp
FROM (
SELECT id, DRIVER, DROPno,
CASE
WHEN DROPno = 'ReturnToBase' THEN 1
ELSE 0
END AS flag
FROM rounds ) AS t
此查询在SUM
子句中使用带ORDER BY
的窗口版OVER
来计算运行总计。此版本的SUM
可从SQL Server 2012开始提供AFAIK。
为了获得正确的GROUP
值,我们需要充分利用这个运行总值。
编辑:(归功于@Conrad Frix)
使用CROSS APPLY
代替内嵌视图可以大大简化:
SELECT id, DRIVER, DROPno,
1 + SUM(x.flag) OVER (PARTITION BY DRIVER ORDER BY id) - x.flag
FROM rounds
CROSS APPLY (SELECT CASE WHEN DROPno = 'ReturnToBase' THEN 1 ELSE 0 END) AS x(flag)
答案 1 :(得分:2)
为您的示例添加了一个顺序ID列,以便在递归CTE中使用:
with cte as (
select ID,DRIVER,DROPno,1 as GRP
FROM rounds
where ID = 1
union all
select a.ID
,a.DRIVER
,a.DROPno
,case when b.DROPno = 'ReturnToBase'
or b.DRIVER <> a.DRIVER then b.GRP + 1
else b.GRP end
from rounds a
inner join cte b
on a.ID = b.ID + 1
)
select * from cte