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

Oracle SQL中LISTAGG聚合重复名称去重及查询修正问询

解决LISTAGG返回重复姓名的问题

嘿,我来帮你搞定这个重复姓名的问题!咱们一步步来分析:

当前查询的问题

你的原查询之所以会返回重复姓名,核心原因是关联FILM_PRODUKCE表时产生了重复行。比如同一个人可能在同一部电影的FILM_PRODUKCE里有多条记录(比如兼任多个生产角色),当你直接和OSOBA表JOIN后,这些重复的记录会被保留,最终LISTAGG会把同一个名字多次拼接进去。

解决方案

根据你使用的Oracle版本,有两种简单的解决方式:

方式1:使用DISTINCT直接去重(Oracle 12cR2及以上版本支持)

如果你的Oracle版本是12cR2或更新的,直接在LISTAGG里加上DISTINCT关键字就能自动去重,这是最简洁的方法:

SELECT 
    FILM.NAZEV, 
    FILM.VYDANI, 
    FILM.DELKA, 
    FILM.CENA, 
    LISTAGG(DISTINCT OSOBA.JMENO, ',') WITHIN GROUP (ORDER BY OSOBA.JMENO) AS Produkce 
FROM FILM_PRODEJNA 
INNER JOIN FILM ON FILM_PRODEJNA.FILM_ID_FILM = FILM.ID_FILM 
LEFT JOIN FILM_PRODUKCE ON FILM_PRODUKCE.FILM_ID_FILM = FILM.ID_FILM -- 补全你原语句未写完的关联条件
LEFT JOIN OSOBA ON FILM_PRODUKCE.OSOBA_ID_OSOBA = OSOBA.ID_OSOBA -- 假设关联OSOBA表的条件为该字段
GROUP BY FILM.NAZEV, FILM.VYDANI, FILM.DELKA, FILM.CENA;

方式2:子查询先去重(兼容所有Oracle版本)

如果你的Oracle版本不支持LISTAGG里的DISTINCT,可以先通过子查询把FILM_PRODUKCE和OSOBA的关联结果去重,再进行聚合:

SELECT 
    f.NAZEV, 
    f.VYDANI, 
    f.DELKA, 
    f.CENA, 
    LISTAGG(p.JMENO, ',') WITHIN GROUP (ORDER BY p.JMENO) AS Produkce 
FROM FILM_PRODEJNA fp
INNER JOIN FILM f ON fp.FILM_ID_FILM = f.ID_FILM 
LEFT JOIN (
    -- 子查询先获取每部电影对应的唯一姓名
    SELECT DISTINCT 
        fp2.FILM_ID_FILM, 
        o.JMENO 
    FROM FILM_PRODUKCE fp2
    JOIN OSOBA o ON fp2.OSOBA_ID_OSOBA = o.ID_OSOBA -- 补全关联条件
) p ON p.FILM_ID_FILM = f.ID_FILM 
GROUP BY f.NAZEV, f.VYDANI, f.DELKA, f.CENA;

额外注意点

  • 确保你的GROUP BY子句包含了所有非聚合字段(也就是SELECT里除了LISTAGG之外的所有字段),避免分组逻辑错误。
  • 如果FILM表的NAZEV(电影名)不是唯一标识,建议改用FILM.ID_FILM作为分组依据之一,避免不同电影因为同名被错误合并。

内容的提问来源于stack exchange,提问作者Jakub Stanek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:24:24