Oracle 19c中基于OR逻辑忽略空值对两列分组统计的实现
在Oracle 19c中实现基于逻辑键的分组统计
完全可以实现该需求。根据你的数据模型(ID1与ID2一一对应),可以通过**递归关联(CONNECT BY)**结合窗口函数,或者利用子查询匹配基准组的方式完成分组统计。以下是两种可行的SQL实现方案:
方案1:使用CONNECT BY递归分组
该方案通过递归关联所有逻辑上属于同一组的行,再统一统计分组结果:
SELECT DISTINCT MAX(ID1) OVER (PARTITION BY group_key) AS ID1, MAX(ID2) OVER (PARTITION BY group_key) AS ID2, COUNT(*) OVER (PARTITION BY group_key) AS COUNT FROM ( SELECT t.*, -- 生成唯一分组标识:取递归链中根节点的ID组合 CONNECT_BY_ROOT ID1 || '|' || CONNECT_BY_ROOT ID2 AS group_key FROM your_table t CONNECT BY NOCYCLE -- 关联规则:ID1非空且相同,或ID2非空且相同 (PRIOR ID1 = ID1 AND ID1 IS NOT NULL) OR (PRIOR ID2 = ID2 AND ID2 IS NOT NULL) ) -- 仅保留包含完整ID的组代表行 WHERE ID1 IS NOT NULL AND ID2 IS NOT NULL ORDER BY ID1;
逻辑说明:
- 内层子查询通过
CONNECT BY NOCYCLE将所有关联行(比如ID1为A的行、ID2为1的行)归为同一递归链,用CONNECT_BY_ROOT生成该链的唯一分组标识。 - 外层通过窗口函数
MAX()获取每组的非空ID1和ID2作为结果键,COUNT()统计组内行数,最后过滤掉不完整的行得到目标结果。
方案2:基于基准组匹配统计
先提取所有包含完整ID的基准组,再将所有行匹配到对应基准组统计:
WITH base_groups AS ( -- 提取所有ID1和ID2均非空的基准组(根据数据模型,这些组是唯一的) SELECT ID1, ID2 FROM your_table WHERE ID1 IS NOT NULL AND ID2 IS NOT NULL ) SELECT bg.ID1, bg.ID2, COUNT(*) AS COUNT FROM your_table yt JOIN base_groups bg -- 匹配规则:行的ID1与基准组ID1相同,或行的ID2与基准组ID2相同 ON (yt.ID1 = bg.ID1 AND yt.ID1 IS NOT NULL) OR (yt.ID2 = bg.ID2 AND yt.ID2 IS NOT NULL) GROUP BY bg.ID1, bg.ID2 ORDER BY bg.ID1;
逻辑说明:
- 首先通过CTE获取所有完整的ID1-ID2基准对(即结果中需要展示的键)。
- 将原表所有行与基准组关联,匹配条件为行的非空ID与基准组对应ID一致,最后按基准组分组统计行数。
两种方案均能在Oracle 19c中正常运行,且符合你的数据模型约束(不会出现ID1或ID2对应多个基准组的情况)。
内容的提问来源于stack exchange,提问作者Vadim Lotarev
相关产品推荐
相关产品推荐

