滚动列更改

问题描述 投票:0回答:1

下表 - 按[低]、[高]排序

团体 部分
A 01 01 10
A 01 11 15
A 01 18 18
A 01 19 25
A 02 26 30
A 02 31 32
A 01 33 40
A 01 41 41

通过使用上面的表格,我想创建另一个表格(下面的示例),因此每次在

[Section]
更改之前,我都希望获得
MIN(Low)
MAX(High)

团体 部分
A 01 01 25
A 02 26 32
A 01 33 41

显然,这太简单了,行不通

select [group], [section], min([low]), max([high])
from table
group by [group], [section]
sql sql-server gaps-and-islands
1个回答
0
投票

这称为间隙和孤岛,您希望将事物分组,直到发生变化。

我通常采用这个三阶段解决方案:

;WITH data AS (
    SELECT  *
    FROM
    (
        VALUES  (N'A', N'01', N'01', 10)
        ,   (N'A', N'01', N'11', 15)
        ,   (N'A', N'01', N'18', 18)
        ,   (N'A', N'01', N'19', 25)
        ,   (N'A', N'02', N'26', 30)
        ,   (N'A', N'02', N'31', 32)
        ,   (N'A', N'01', N'33', 40)
        ,   (N'A', N'01', N'41', 41)
    ) t ([Group],Section,Low,High)
)
SELECT  grouping, [group], MIN(Low), MAX(high) /* 3 */
FROM    (
    SELECT  COUNT(flag) OVER(partition BY [group] ORDER BY low rows BETWEEN unbounded preceding AND CURRENT row) AS grouping /* 2 */
    ,   *
    FROM    (
        SELECT  CASE WHEN lag(section) OVER(partition BY [group] ORDER BY low) <> section THEN 1 END AS flag /* 1 */
        ,   *
        FROM    data
        ) x
    ) x
GROUP BY [group], grouping
  1. 您创建一个
    flag
    ,它表示如果先前的值与当前值不同,则每次此标志变为 1 时,都是新组的开始。
  2. 使用有序窗口函数对标志进行计数或汇总。这将创建最终的分组。
    rows between unbounded preceding and current row
    主要是 sql server goo,它提高了窗口聚合的性能
  3. 现在,您已准备好根据我们的新分组列实际执行聚合,这是一个简单的 GROUP BY。

输出:

分组 最小低 最大高度
0 A 01 25
1 A 26 32
2 A 33 41

PS:注意低/高值,因为你使用

01
它们可能不是真正的整数而是 varchar,那么你必须确保它们都填充到相同的长度,因为 varchar
99
更比
100

© www.soinside.com 2019 - 2024. All rights reserved.