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

如何在单行中左连接两张表(Oracle 11g/标准SQL)并实现指定结果

实现单行左连接的标准化方案(Oracle 11g/标准SQL)

嘿,这个需求完全可以用标准化的SQL语法来实现,不用什么冷门技巧~ 下面根据你要的单行呈现方式,给你两种常见的方案,不管是Oracle 11g还是标准SQL都能覆盖到:

方案1:将子项拼接为单个字符串(最常用)

如果只是想把父项对应的所有子项放在同一行的一个字段里,Oracle 11g自带的LISTAGG函数就非常合适,这也是Oracle官方推荐的字符串聚合方法;如果是标准SQL环境,可使用STRING_AGG(不同数据库可能有细微差异,但逻辑一致)。

示例代码(Oracle 11g)

-- 假设父表为parent,主键parent_id;子表为child,主键child_id,关联字段parent_id
SELECT 
    p.parent_id,
    -- 用逗号分隔子项,也可以换成其他分隔符
    LISTAGG(c.child_id, ', ') WITHIN GROUP (ORDER BY c.child_id) AS child_items
FROM parent p
-- 左连接保证父表所有行都被保留,哪怕没有子项
LEFT JOIN child c ON p.parent_id = c.parent_id
GROUP BY p.parent_id;

效果:p1会显示c1, c2,p2的child_items字段为NULL(可以用NVL(LISTAGG(...), '无子女')替换成你想要的提示文本)。

标准SQL版本(兼容多数数据库)

SELECT 
    p.parent_id,
    STRING_AGG(c.child_id, ', ') AS child_items
FROM parent p
LEFT JOIN child c ON p.parent_id = c.parent_id
GROUP BY p.parent_id;

方案2:将子项拆分为单独的列(如child1、child2)

如果需要把每个子项放在独立的字段里(比如p1的两个子项分别显示为child_1和child_2),可以用窗口函数ROW_NUMBER()结合条件聚合来实现,这是标准SQL兼容的写法,Oracle 11g也支持。

示例代码

WITH ranked_children AS (
    -- 给每个父项的子项按顺序编号
    SELECT 
        child_id,
        parent_id,
        ROW_NUMBER() OVER (PARTITION BY parent_id ORDER BY child_id) AS rn
    FROM child
)
SELECT 
    p.parent_id,
    -- 取第1个、第2个子项,没有的话显示NULL
    MAX(CASE WHEN rc.rn = 1 THEN rc.child_id END) AS child_1,
    MAX(CASE WHEN rc.rn = 2 THEN rc.child_id END) AS child_2
FROM parent p
LEFT JOIN ranked_children rc ON p.parent_id = rc.parent_id
GROUP BY p.parent_id;

效果:p1的child_1为c1,child_2为c2;p2的两个子字段都是NULL。如果子项数量不确定,也可以用Oracle 11g的PIVOT语法,写法会更简洁,但兼容性稍差。


核心逻辑其实就是:用LEFT JOIN保留父表的所有行,再通过聚合函数(LISTAGG/STRING_AGG/MAX)或窗口函数将子表的多行数据合并到父表的单行中,这些都是SQL标准里的常规操作,不需要特殊的连接类型或保留关键字,组合基础语法就能实现。

内容的提问来源于stack exchange,提问作者Prefijo Sustantivo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:02:53