【问题标题】:How can I structure this Oracle SQL query如何构建此 Oracle SQL 查询
【发布时间】:2021-10-26 16:38:58
【问题描述】:

我需要检索由“,”分隔的“CARGO#”的一个或多个名称,由“PNTO_VNTA”过滤

我需要这样的输出:

我做了很多测试,但他们以这种方式给我带来了结果:

这是我正在使用的代码

 SELECT
    s.PNTO_VNTA,
    LISTAGG (g.CARGO), ', ') WITHIN GROUP (ORDER BY g.CARGO) OVER()  PRODUCTOS
FROM
    PNTOS_VNTA s,
    CARGOS g
WHERE
    s.crgo = g.CARGO
    AND s.PNTO_VNTA = 12345
    GROUP BY s.PNTO_VNTA,
    g.cargo
    ;

【问题讨论】:

    标签: sql oracle listagg


    【解决方案1】:

    您同时按pnto_vntacargo 进行分组,因此每个组合都会得到一行;然后聚合将只有一个值。您似乎已尝试通过添加 over() 子句来对 listagg() 调用进行分析来弥补这一点。

    如果你改变这两个,你应该得到你想要的:

    SELECT
        s.PNTO_VNTA,
        LISTAGG (g.CARGO, ', ') WITHIN GROUP (ORDER BY g.CARGO) PRODUCTOS
    FROM
        PNTOS_VNTA s,
        CARGOS g
    WHERE
        s.crgo = g.CARGO
        AND s.PNTO_VNTA = 12345
        GROUP BY s.PNTO_VNTA
        ;
    

    或使用 ANSI 连接语法:

    SELECT
        s.PNTO_VNTA,
        LISTAGG (g.CARGO, ', ') WITHIN GROUP (ORDER BY g.CARGO) PRODUCTOS
    FROM PNTOS_VNTA s
    JOIN CARGOS g ON s.crgo = g.CARGO
    WHERE s.PNTO_VNTA = 12345
    GROUP BY s.PNTO_VNTA
    ;
    

    虽然看起来你不需要加入;除非您有空值或孤儿,否则您可能可以这样做:

    SELECT
        s.PNTO_VNTA,
        LISTAGG (s.CRGO, ', ') WITHIN GROUP (ORDER BY s.CRGO) PRODUCTOS
    FROM PNTOS_VNTA s
    WHERE s.PNTO_VNTA = 12345
    GROUP BY s.PNTO_VNTA
    ;
    

    db<>fiddle

    (我在所有这些中都留下了s.crgo;不确定这是否是您的问题中的拼写错误。)

    【讨论】:

    • 感谢您的回答,我已经尝试过您的解决方案摆脱了over(),但是当我这样做时,我收到了这个错误ORA-01489: string concatenation result is too long
    • 你不应该为你展示的例子,因为它只有三个货物值。如果您有其他(真实的)pnto_vnta 值有很多 cargo 值,那么这些值也会超过分析版本的 4k 字符串限制。不过,这是一个不同的问题,之前已经被问过很多次了——例如here
    • 我知道第一个例子我不应该得到那个错误,但我仍然得到它并且不知道为什么,我尝试添加这个rownum = 1,但我在@中只得到一个结果987654337@
    • 我不确定你的意思。我添加了一个 dbfiddle 表明它可以工作。如果您正在做一些更复杂的事情,那么作为 minimal reproducible example 的新问题 - 包括演示问题的 DDL 和示例数据。
    猜你喜欢
    • 2018-08-15
    • 1970-01-01
    • 2017-03-14
    • 1970-01-01
    • 2016-06-01
    • 2023-01-17
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    相关资源
    最近更新 更多