как исправить wm_concat в оракуле 12c - PullRequest
0 голосов
/ 01 июля 2019

Поскольку wm_concat устарела в oracle 12C, мне нужно изменить приведенный ниже запрос, я пытался использовать LISTAGG, но он не работал

SELECT WM_CONCAT(CLRR.CLNTNUM)
    || '#'
    ||WM_CONCAT(trim(trim(clnt.salutl)
    || ' '
    || trim(clnt.lgivname)
    || ' '
    || trim(clnt.lsurname)))
  FROM ODSLIFEASIA.CLRRPF CLRR,
    odslifeasia.clntpf clnt
  WHERE clnt.clntnum             = CLRR.CLNTNUM
  AND CLRRROLE                   = 'LF'
  AND clnt.validflag            IN ('1', '3')
  AND NVL(USED2B, 'X')          <> 'U'
  AND rownum                     <5;

Я пробовал приведенный ниже код, но он не работал:

SELECT LISTAGG(CLRR.CLNTNUM,',') within group (order by CLRR.CLNTNUM)--WM_CONCAT(CLRR.CLNTNUM)
        || '#'
        ||LISTAGG(trim(trim(clnt.salutl,',') within group (order by CLRR.clnt.salutl)--WM_CONCAT(trim(trim(clnt.salutl)
        || ' '
        || trim(clnt.lgivname)
        || ' '
        || trim(clnt.lsurname)))
      FROM ODSLIFEASIA.CLRRPF CLRR,
        odslifeasia.clntpf clnt
      WHERE clnt.clntnum             = CLRR.CLNTNUM
      AND CLRRROLE                   = 'LF'
      AND clnt.validflag            IN ('1', '3')
      AND NVL(USED2B, 'X')          <> 'U'
      AND rownum                     <5;

Я попробовал приведенный ниже код, но он не работал:

    SELECT LISTAGG(CLRR.CLNTNUM,',') within group (order by CLRR.CLNTNUM)--WM_CONCAT(CLRR.CLNTNUM)
    || '#'
    ||LISTAGG(trim(trim(clnt.salutl,',') within group (order by CLRR.clnt.salutl)--WM_CONCAT(trim(trim(clnt.salutl)
    || ' '
    || trim(clnt.lgivname)
    || ' '
    || trim(clnt.lsurname)))
  FROM ODSLIFEASIA.CLRRPF CLRR,
    odslifeasia.clntpf clnt
  WHERE clnt.clntnum             = CLRR.CLNTNUM
  AND CLRRROLE                   = 'LF'
  AND clnt.validflag            IN ('1', '3')
  AND NVL(USED2B, 'X')          <> 'U'
  AND rownum                     <5;

Я не могу получить вывод с LISTAGG, но с wm_concat Я получаю:

53155087,53155088,53155089,53155090 # Андеррайтинг MR IONE, Андеррайтинг MR IONE, Андеррайтинг MR IONE, Андеррайтинг MR IONE

То же самое, что я ожидаю

Ответы [ 2 ]

3 голосов
/ 01 июля 2019

Сначала объедините значения salut1, lgivname и lsurname, затем используйте listagg (). Должно быть:

select listagg(clrr.clntnum,',') 
           within group (order by clrr.clntnum) || '#' ||
       listagg(trim(trim(clnt.salutl)|| ' '|| 
                    trim(clnt.lgivname)|| ' ' || 
                    trim(clnt.lsurname)), ',')
           within group (order by clnt.salutl)
      from odslifeasia.clrrpf clrr
      join odslifeasia.clntpf clnt on clnt.clntnum = clrr.clntnum
      where clrrrole           = 'LF'
        and clnt.validflag     in ('1', '3')
        and nvl(used2b, 'x')   <> 'U'
        and rownum             < 5;

Надеюсь, я не сделал опечатку. Также используйте join.

Кстати: вы используете разные порядки для обоих списков, может быть, было бы лучше использовать один и тот же?

1 голос
/ 01 июля 2019

Точное форматирование запроса поможет вам узнать, где должны быть аргументы функции.

Синтаксис LISTAGG:

LISTAGG( value, separator ) WITHIN GROUP ( ORDER BY columns )

Здесь value - это конкатенация приветствия, имени и фамилии, а затем строка separator должна идти после этого. У вас были скобки в неправильных местах, поэтому аргумент-разделитель для функции LISTAGG был внутри функции TRIM.

SELECT LISTAGG(
         CLRR.CLNTNUM,
         ','
       ) WITHIN GROUP (ORDER BY CLRR.CLNTNUM)
       || '#'
       || LISTAGG(
            trim(
              trim(clnt.salutl)
              || ' '
              || trim(clnt.lgivname)
              || ' '
              || trim(clnt.lsurname)
            ),
            ','
          ) WITHIN GROUP (ORDER BY CLRR.clnt.salutl)
FROM   ODSLIFEASIA.CLRRPF CLRR
       INNER JOIN odslifeasia.clntpf clnt
       ON ( clnt.clntnum = CLRR.CLNTNUM)
WHERE CLRRROLE                   = 'LF'
AND   clnt.validflag            IN ('1', '3')
AND   NVL(USED2B, 'X')          <> 'U'
AND   rownum                    <5;
...