listagg中没有嵌套查询的不同值

时间:2017-05-24 20:58:50

标签: sql oracle

我正在尝试聚合列:

SELECT LISTAGG(name, ';  ') WITHIN GROUP (ORDER BY name)
FROM tbl_a
INNER JOIN tbl_b ON tbl_a.foo = tbl_b.foo
WHERE tbl_a.id = 12345

这很好但我想删除重复项,所以我执行一个嵌套查询来过滤不同的。

SELECT LISTAGG(name, ';  ') WITHIN GROUP (ORDER BY name)
FROM
(
    SELECT DISTINCT tbl_a.name
    FROM tbl_a
    INNER JOIN tbl_b ON tbl_a.foo = tbl_b.foo
    WHERE tbl_a.id = 12345
)

然后我想把它放在另一个查询中,这样我就可以过滤变量值,而不是常量12345

SELECT
tbl_c.bar,
(
    SELECT LISTAGG(name, ';  ') WITHIN GROUP (ORDER BY name)
    FROM
    (
        SELECT DISTINCT tbl_a.name
        FROM tbl_a
        INNER JOIN tbl_b ON tbl_a.foo = tbl_b.foo
        WHERE tbl_a.id = tbl_c.bar
    )
) as names
FROM tbl_c;
/* gets complicated, C is joined with other tables and stuff */

由于tbl_c.bar嵌套两次,因此它显示为无效的标识符。因此,这种方法是不可能的。

有没有办法listagg,丢弃重复但没有嵌套?

我希望将结果汇总到一个单元格中,例如name1; name2; name3

我根本不关心表现。但是,可读性会很好。

4 个答案:

答案 0 :(得分:2)

这是一个令人讨厌的解决方案:

SELECT tbl_c.bar,
       (SELECT LISTAGG(name, ';  ') WITHIN GROUP (ORDER BY name)
        FROM (SELECT tbla.id, tbl_a.name
              FROM tbl_a INNER JOIN
                   tbl_b
                   ON tbl_a.foo = tbl_b.foo
              GROUP BY tbl_a.id
             ) x
        WHERE x.id = tbl_c.bar
       ) as names
FROM tbl_c;

答案 1 :(得分:1)

这个查询可能需要一些调整,但我会使用一个因子子查询。像

这样的东西
WITH unagg AS (
        SELECT DISTINCT tbl_a.name AS names, 
               first_value(foo) over (partition by name order by foo)
        FROM tbl_a )
SELECT LISTAGG(names, ';  ') WITHIN GROUP (ORDER BY names)
  FROM unagg
  JOIN tbl_b USING (foo)
 WHERE --condition

答案 2 :(得分:0)

RLOG's answer激励我去解决"我自己。这可能效率低下,但这对我的用例并不重要。

我没有在查询第二个嵌套查询中进行过滤,而是获取所有内容,然后在第一个嵌套查询中过滤结果。

SELECT tbl_c.bar,
(
    WITH all_names AS (
        SELECT DISTINCT tbl_a.name
        FROM tbl_a
        INNER JOIN tbl_b ON tbl_a.foo = tbl_b.foo
    )
    SELECT LISTAGG(name, ';  ') WITHIN GROUP (ORDER BY name)
    FROM all_names
    WHERE tbl_a.id = tbl_c.bar
) as names
FROM tbl_c;

答案 3 :(得分:0)

我认为你的答案可以缩短到这一点。

  WITH all_names AS (
SELECT DISTINCT tbl_a.name
        FROM tbl_a
        INNER JOIN tbl_b ON tbl_a.foo = tbl_b.foo
        INNER JOIN tbl_c ON tbl_a.id = tbl_c.bar
  )
SELECT LISTAGG(name, ';  ') WITHIN GROUP (ORDER BY name)
  FROM all_names;