TSQL - 难以分组
Posted
技术标签:
【中文标题】TSQL - 难以分组【英文标题】:TSQL - Difficult Grouping 【发布时间】:2015-08-27 15:19:21 【问题描述】:请看小提琴: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
【问题讨论】:
能否请您添加到目前为止您尝试过的sql。看起来 Row_Number 应该适合这里 您正在查看某种递归 LEAD LAG 公用表表达式来完成此操作。 还有一个顺序标识符,抱歉我应该在示例中包含它。 下降 6,7 应该是 7,8 还是样本正确? 能否为以后的读者添加顺序标识符?答案中也需要它,所以不妨使用正确的列名。试试Partition by driver Order By SequentialColumn
会有帮助吗?
【参考方案1】:
您可以使用以下查询:
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
Demo here
此查询在OVER
子句中使用SUM
的窗口版本和ORDER BY
来计算运行总计。此版本的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)
Demo here
【讨论】:
完美,我离题了。谢谢 如果您想为单个计算设置别名,您可能需要考虑使用交叉应用而不是内联视图。for example【参考方案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
SQL Fiddle
【讨论】:
以上是关于TSQL - 难以分组的主要内容,如果未能解决你的问题,请参考以下文章