SQL关联查询中如何仅在首次出现时展示child.col字段重复值
实现方案
你可以用标准SQL支持的ROW_NUMBER()窗口函数实现需求,对原有复杂查询的侵入性极低,只需要将原有查询作为子查询嵌套即可。
核心逻辑说明
- 用
PARTITION BY child.name将相同子项的行划分为同一组 - 用
ORDER BY指定你判定「首次出现」的排序规则(示例中按parent.name排序,你可以根据业务替换为创建时间、ID等字段) - 用
CASE语句判断组内行序号为1时返回child.col的值,否则返回空值
代码实现
基础版本(兼容所有支持窗口函数的数据库:MySQL8+、PostgreSQL、SQL Server、Oracle等)
如果需要先得到带instance序号的结果:
SELECT parent.name, child.name, child.col, ROW_NUMBER() OVER (PARTITION BY child.name ORDER BY parent.name) AS instance FROM parent JOIN child ON parent.match = child.match
如果直接得到仅首次展示child.col的最终结果:
SELECT parent.name, child.name, CASE WHEN ROW_NUMBER() OVER (PARTITION BY child.name ORDER BY parent.name) = 1 THEN child.col ELSE NULL -- 如需显示空字符串可替换为 '' END AS child_col FROM parent JOIN child ON parent.match = child.match
适配复杂查询的写法
如果你的原有查询逻辑非常复杂,不需要修改原有逻辑,直接将其作为子查询嵌套即可:
SELECT name, child_name, CASE WHEN rn = 1 THEN child_col ELSE NULL END AS child_col FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY child_name ORDER BY 你业务中判定首次出现的排序字段) AS rn FROM ( -- 此处直接粘贴你原有复杂查询的完整代码即可 SELECT ... 原有复杂查询逻辑 ... ) origin_query ) t
MySQL 5.x兼容版本(不支持窗口函数的场景)
SELECT name, child_name, CASE WHEN @prev_child = child_name THEN NULL ELSE child_col END AS child_col, @prev_child := child_name FROM ( -- 先排序,优先按child.name分组,再按首次出现规则排序 SELECT parent.name, child.name AS child_name, child.col AS child_col FROM parent JOIN child ON parent.match = child.match ORDER BY child.name, parent.name ) t, (SELECT @prev_child := '') AS init
内容的提问来源于stack exchange,提问作者GammaGames
相关产品推荐
相关产品推荐

