我试图寻找解决方案,但没有成功。 如何将表格分组,如下所示:
from | to | zone
1 | 1 | 1
1 | 2 | 1
1 | 3 | 1
1 | 4 | 2
1 | 5 | 2
1 | 6 | 2
1 | 7 | 1
1 | 8 | 1
1 | 9 | 1
1 | 10 | 9
2 | 1 | 7
2 | 2 | 7
2 | 3 | 7
2 | 4 | 2
2 | 5 | 2
2 | 6 | 2
2 | 7 | 7
2 | 8 | 7
2 | 9 | 7
看起来像这样:
from | to | zone
1 | 1-3 | 1
1 | 4-6 | 2
1 | 7-9 | 1
1 | 10 | 9
2 | 1-3 | 7
2 | 4-6 | 2
2 | 7-9 | 7
感谢您的帮助
答案 0 :(得分:2)
这里的一种方法是使用行号方法的差异,使用to
列作为一个行号,使用from
和zone
作为分区上的行号其他行号。有一点难以解释为什么这么多用词。最好查看下面的演示链接来探索查询。
WITH cte AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [from], zone ORDER BY [to]) rn
FROM yourTable
)
SELECT
t.[from],
CONVERT(varchar(10), MIN(t.[to])) + '-' + CONVERT(varchar(10), MAX([to])) AS [to],
t.zone
FROM cte t
GROUP BY
t.[from],
t.zone,
t.[to] - t.rn
ORDER BY
t.[from],
MIN(t.[to]);
在这里演示:
答案 1 :(得分:1)
这通常被称为 Gaps and Islands 问题。如果您使用的是SQL Server 2012+
,那么
;WITH cte
AS (SELECT *,
Sum(CASE WHEN zone = prev_zone THEN 0 ELSE 1 END)OVER(partition BY [from] ORDER BY [to]) AS grp
FROM (SELECT *,
Lag(zone)OVER(partition BY [from] ORDER BY [to]) AS prev_zone
FROM yourtable ) cs ([from], [to], zone)) a)
SELECT [from],
[to] = Concat(Min([to]), '-', Max([to])),
zone = Min(zone)
FROM cte
GROUP BY [from],grp
答案 2 :(得分:0)
;with mycte
AS
(
select
,[from]
,min([to]) minto
,max([to]) maxto
,[zone]
from
mytable
group by
[from]
,[zone]
)
[from] AS [from]
,concat(minto, '-', maxto) AS [to]
,[zone] AS [zone]
from
mycte