sql - 将行分组到范围内,同时也显示间隙
问题描述
我需要一个数据库选择查询解决方案,用于将一系列细分细节转换为它的汇总版本,可能在一个视图中。考虑下表。它有一个复合主键 ( PK_1
, PK_2
, PK_3
, 和SEQUENCE_NO
)。
PK_1 PK_2 PK_3 SEQUENCE_NO STATUS_CODE
======== ==== ==== =========== ===========
20200421 A 1 1 Y
20200421 A 1 2 Y
20200421 A 1 3 Y
20200421 A 1 4 N
20200421 A 1 5 Y
20200421 A 1 6 Y
20200421 A 2 7 Y
20200421 A 2 8 Y
20200421 B 3 9 Y
20200421 B 3 10 Y
20200421 B 3 11 Y
20200422 B 3 11 Y
仅包括带有STATUS_CODE
“Y”的所有记录,如何以连续记录的方式呈现记录,分别对应于它们的复合主键,形成值范围(由SEQUENCE_FROM
and表示SEQUENCE_TO
,见下文),同时显示可能表明的间隙是缺失的行,还是带有STATUS_CODE
非“Y”值的行?
PK_1 PK_2 PK_3 SEQUENCE_FROM SEQUENCE_TO
======== ==== ==== ============= ===========
20200421 A 1 1 3
20200421 A 1 5 6
20200421 A 2 7 8
20200421 B 3 9 11
20200422 B 3 11 11
我使用过MIN
,MAX
但显然它不适合显示范围之间的差距。
解决方案
这是一个空白和孤岛问题。这是ROW_NUMBER
使用行数差异法解决的一种方法:
WITH cte AS (
SELECT t.*, SEQUENCE_NO -
ROW_NUMBER() OVER (PARTITION BY PK_1, PK_2, PK_3 ORDER BY SEQUENCE_NO) AS diff
FROM yourTable t
WHERE STATUS_CODE = 'Y'
)
SELECT
PK_1,
PK_2,
PK_3,
MIN(SEQUENCE_NO) AS SEQUENCE_FROM,
MAX(SEQUENCE_NO) AS SEQUENCE_TO
FROM cte
GROUP BY
PK_1,
PK_2,
PK_3,
(rn1 - rn2)
ORDER BY
PK_1,
PK_2,
PK_3;
演示
这里使用的逻辑的关键是,我们通过获取序列号和 a 之间的差异,在每个PK_1
, PK_2
,分区内为每个岛形成一个动态组号。这种差异保证对于每个岛屿始终是唯一的。PK_3
ROW_NUMBER
推荐阅读
- python - 用于许多数组的 Python np.convolve/SUMPRODUCT
- phpmyadmin - 检查 MariaDB 中的约束 SQL
- php - 如何将两个实体方法合并为一个
- r - 有没有一种“更干净”的方式来连接查询字符串?
- php - 如何正确清除 json_encode 错误状态?
- php - 退出在线网站时会话不会破坏,但可以与离线网站一起使用
- typescript - 打字稿:为什么打字稿允许我用错误的接口类型调用函数
- javascript - 如何启用对启用了 Google Compute Engine IAP 的负载均衡器的 CORS 请求?
- html - 如何编写 HTML?[使用 Material Design Components 的依赖下拉列表]
- ocaml - 调用后打印函数 (ocaml)