SQL Server - 在按特定列分组时构建动态范围的数字
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL Server - 在按特定列分组时构建动态范围的数字相关的知识,希望对你有一定的参考价值。
我有以下数据:
ID Days
----------------------- --------
1 5
1 10
1 15
2 5
2 13
2 15
我试图根据他们的ID进行分组,根据日期建立一系列数字。
对于ID组1:范围从5开始到9结束。下一个范围是10-14,然后最终范围是15-9999
对于ID组2:范围从5开始到12结束。下一个范围是13-14,然后最终范围是15-9999
结果表看起来像这样:
RangeStart RangeEnd RangeText ID
----------- ----------- --------- ----
5 9 5 - 9 1
10 14 10 - 14 1
15 9999 15 - 9999 1
5 12 5 - 12 2
13 14 13 - 14 2
15 9999 15 - 9999 2
我试图使用CTE,但只有当我没有按ID分组时才有效。
Declare @RangeTable Table
(
ID Int,
RangeStart INT,
RangeEnd INT,
RangeText Varchar(50),
);with CTE as (
SELECT temp.Days,
rn = ROW_NUMBER() over(order by temp.Days asc),
temp.ID
FROM @TableWithDays temp)
INSERT @RangeTable
SELECT
ID= d1.ID,
RangeStart= ISNULL(d1.Days, 0),
RangeEnd = ISNULL(d2.Days- 1, 9999),
RangeText =
CASE WHEN (d1.Days = d2.Days - 1)
THEN CAST(d1.Days AS VARCHAR(100))
ELSE
ISNULL(CAST(d1.Days AS VARCHAR(100)),'0') + ISNULL(' - '+
CAST(d2.Days - 1 AS VARCHAR(100)),' - 9999')END
FROM
CTE d1 LEFT JOIN
CTE d2
ON d1.rn = d2.rn - 1
答案
您可以使用递归CTE。这对lead()
来说会更简单,但是没有。所以:
with t as (
select t.*, t2.days as next_days
from @TableWithDays t outer apply
(select top (1) t2.*
from @TableWithDays t2
where t2.id = t.id and t2.days > t.days
order by t2.days desc
) t2
),
cte as (
select t.id, t.days, t.next_days
from t
union all
select cte.id, cte.days + 1, cte.next_days
from cte
where cte.days < cte.next_days or
(cte.days < 9999 and cte.next_days is null)
)
select *
from cte
with option (maxrecursion 0);
以上是关于SQL Server - 在按特定列分组时构建动态范围的数字的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server 动态行转列(参数化表名分组列行转列字段字段值)
根据 SQL Server 2008 R2 中特定列中的模式更改对行进行分组