You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL数据筛选技术问询:如何保留有子项的父行有效记录与无任何子项的父行,移除已有子项父行的空子项记录

解决父子关系数据的筛选问题

我来帮你搞定这个数据筛选的需求,你的核心规则其实很明确:

  • 要是某个父行有至少一条非空的child记录,那它对应的空child记录就得删掉
  • 要是某个父行压根没有任何非空child记录(比如示例里的C),那它的空child记录得保留

方案一:用窗口函数实现(推荐,逻辑清晰)

这种方式利用窗口函数统计每个父行的非空child数量,筛选逻辑一目了然:

SELECT parent, child
FROM (
    SELECT 
        parent, 
        child,
        -- 统计当前父行下非空child的总数(COUNT自动忽略NULL)
        COUNT(child) OVER (PARTITION BY parent) AS non_null_child_count
    FROM my_table
) AS sub_query
-- 筛选条件:要么child非空,要么该父行没有任何非空child
WHERE child IS NOT NULL OR non_null_child_count = 0;

逻辑拆解

  1. 内层子查询里,COUNT(child) OVER (PARTITION BY parent)会给每一行标记出它所属父行的非空child总数——因为COUNT对NULL值不计数,所以这个数值刚好能帮我们判断父行有没有有效子记录。
  2. 外层的筛选条件直接对应你的需求:
    • 只要child不为空,直接保留这条记录
    • 要是某个父行的non_null_child_count是0,说明它没有任何有效子记录,那就保留它的空child记录

用你的示例数据验证

输入数据:

parentchild
AD
A
BE
BF
C

内层子查询会生成这样的中间结果:

parentchildnon_null_child_count
AD1
A1
BE2
BF2
C0

经过外层筛选后,会去掉A对应的空child记录,最终结果完全符合你的期望:

parentchild
AD
BE
BF
C

方案二:兼容旧版数据库的子查询实现

如果你的数据库不支持窗口函数(比如某些老版本的MySQL),可以用关联子查询来实现:

SELECT t1.parent, t1.child
FROM my_table t1
LEFT JOIN (
    -- 先找出所有有非空child记录的父行
    SELECT parent 
    FROM my_table 
    WHERE child IS NOT NULL 
    GROUP BY parent
) t2 ON t1.parent = t2.parent
-- 筛选逻辑:要么当前记录child非空,要么父行不在有非空child的列表里
WHERE t1.child IS NOT NULL OR t2.parent IS NULL;

这个方案的思路是先把所有有有效子记录的父行找出来,然后筛选时排除那些属于这类父行的空child记录,同时保留没有有效子记录的父行的空记录。

内容的提问来源于stack exchange,提问作者Ricardo Francois

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 18:42:37