Получить разные значения с помощью LISTAGG в Oracle 12C - PullRequest
1 голос
/ 25 октября 2019

Я пытаюсь получить несколько составных различных varchars (с именем CODE в запросе) из нескольких строк в нескольких столбцах, используя LISTAGG в oracle 12C, LISTAGG (отличный ...) решаетпроблема на 19c, но я должен работать с 12c.

неожиданный результат

Я получаю вышеуказанный результат, используя этот запрос:


   SELECT
          T.c1 A,
          T.c2 B,
          LISTAGG( TI.CODE , ';' ) WITHIN GROUP (ORDER BY  TI.CODE) AS  COLUMNX1,
          LISTAGG( TE.CODE, ' ;') WITHIN GROUP (ORDER BY  TE.CODE ) AS COLUMNX2,    
          LISTAGG(TR.CODE, '; ') WITHIN GROUP (ORDER BY TR.CODE ) AS COLUMNX3
   FROM  TABLE1 T
          INNER join  TABLE_I TI on  TI.fk_c2 = T.c2
          INNER join  TABLE_E TE on TE.fk_c2 = T.c2
          INNER join TABLE_R TR on TR.fk_c2 = T.c2
          WHERE T.d = *parameter*
          GROUP BY
          T.c1,
          T.c2;

Iхотите получить это:

Ожидаемый результат

Строки, отмеченные желтым, не должны быть извлечены.

В каждой строке результата запроса столбцыCOLUMNX1, COLUMNX2, COLUMNX3 имеют одинаковое количество объединенных строк, поэтому у меня проблема с дублированием.

, кроме того, все TABLE_I, TABLE_E и TABLE_R имеют внешний ключ fk_c2, который ссылается на TABLE1.c2

РЕДАКТИРОВАТЬ:

Я сначала добавил предложение с, чтобы получить различные значения, затем я присоединил его к своему оператору выбора

Ожидаемый результат получен с этим запросом


WITH TEMP AS (

     SELECT fk_c2, LISTAGG(code, ',')  WITHIN GROUP (ORDER BY code) AS X1 
     FROM (
          SELECT DISTINCT * 
          FROM TABLE_I
          GROUP BY fk_c2 ) COLUMNX1

     INNER JOIN
    (SELECT fk_c2, LISTAGG(code, ',') WITHIN GROUP (ORDER BY code) AS X2
      FROM (
           SELECT DISTINCT * 
           FROM TABLE_E)
           GROUP BY fk_c2 ) COLUMNX2
     ON COLUMNX1.fk_c2 = COLUMNX2.fk_c2

     INNER JOIN
    (SELECT fk_c2, LISTAGG(code, ',') WITHIN GROUP (ORDER BY code) AS X3
     FROM(
          SELECT DISTINCT * 
          FROM TABLE_R)
          GROUP BY fk_c2 ) COLUMNX3    
     ON COLUMNX1.fk_c2 = COLUMNX3.fk_c2
       )

     SELECT
         T.c1 A,
         T.c2 B,
         tmp.X1,
         tmp.X2,
         tmp.X3
  FROM  TABLE1 T
         INNER join  temp tmp on  tmp.fk_c2 = T.c2
         WHERE T.d = *parameter*
         GROUP BY
         T.c1,
         T.c2
         tmp.X1,
         tmp.X2,
         tmp.X3;

1 Ответ

0 голосов
/ 25 октября 2019

Вам понадобится дополнительный шаг: сначала найдите отдельные значения, затем агрегируйте их. Например:

SQL> with test (id, col) as
  2    (select 1, 'x' from dual union all
  3     select 1, 'x' from dual union all
  4     --
  5     select 2, 'w' from dual union all
  6     select 2, 't' from dual union all
  7     select 2, 'w' from dual union all
  8     --
  9     select 3, 'i' from dual
 10    ),
 11  -- first find distinct values ...
 12  temp as
 13    (select distinct id, col from test)
 14  -- ... then aggregate them
 15  select id,
 16         listagg(col, ';') within group (order by col) result
 17  from temp
 18  group by id;

        ID RESULT
---------- ----------
         1 x
         2 t;w
         3 i

SQL>
...