Мне нужен результат оператора select в виде нескольких данных о рождении для одного идентификатора

APPLICANT_ID    DATE_OF_BIRTH
206209579       04/29/82
206209579       04/29/82
203276426       06/01/69
203276426       02/03/96
203276426       06/02/99

мне нужен результат как

206209579       04/29/82,04/29/82
203276426       06/01/69,02/03/96

Пожалуйста, предложите его полностью


person Anand Yadav    schedule 24.02.2015    source источник
comment
Есть несколько способов сделать string aggregation. Вам нужно указать свою версию. 11g и выше, вы можете использовать LISTAGG, иначе, если вы используете предыдущую версию, посмотрите мой ответ.   -  person Lalit Kumar B    schedule 24.02.2015


Ответы (2)


В Oracle 11g и выше вы можете использовать listagg:

SELECT   applicant_id,
         LISTAGG(date_of_birth) WITHIN GROUP (ORDER BY date_of_birth)
FROM     my_table
GROUP BY applicant_id 
person Mureinik    schedule 24.02.2015
comment
Исправление - LISTAGG() не List_Agg() - пожалуйста, исправьте. В Oracle 10g есть функция WM_CONCAT(), которую можно использовать. - person Art; 24.02.2015
comment
@Art, wm_concat - это недокументированная функция, которую НЕ предполагается использовать в производственных системах. - person Lalit Kumar B; 24.02.2015
comment
@Art Я вижу, Лалит Кумар Б уже опередил меня в редактировании. Спасибо, что указали на это! - person Mureinik; 24.02.2015
comment
@Art, Кроме того, wm_concat больше не входит в 12c. - person Lalit Kumar B; 27.02.2015
comment
@Mureinik Ссылка кажется неверной, она указывает на функцию LENGTH, а не на LISTAGG. - person Lalit Kumar B; 11.09.2015
comment
@LalitKumarB странно. Не знаю, как это произошло, но сейчас это исправлено. - person Mureinik; 11.09.2015

В качестве альтернативы для версии Oracle до 11g, где LISTAGG не поддерживается, можно использовать функции ROW_NUMBER() и SYS_CONNECT_BY_PATH.

Тестовый пример:

SQL> SELECT * FROM table1;

APPLICANT_ID DATE_OF_B
------------ ---------
   206209579 29-APR-82
   206209579 29-APR-82
   203276426 01-JUN-69
   203276426 03-FEB-96
   203276426 02-JUN-99

SQL>
SQL> SELECT applicant_id,
  2         LTRIM(MAX(SYS_CONNECT_BY_PATH(date_of_birth,','))
  3         KEEP (DENSE_RANK LAST ORDER BY curr),',') AS employees
  4  FROM   (SELECT applicant_id,
  5                 date_of_birth,
  6                 ROW_NUMBER() OVER (PARTITION BY applicant_id ORDER BY date_of_birth) AS curr,
  7                 ROW_NUMBER() OVER (PARTITION BY applicant_id ORDER BY date_of_birth) -1 AS prev
  8          FROM   table1)
  9  GROUP BY applicant_id
 10  CONNECT BY prev = PRIOR curr AND applicant_id = PRIOR applicant_id
 11  START WITH curr = 1;

APPLICANT_ID EMPLOYEES
------------ --------------------------------------------------
   203276426 01-JUN-69,03-FEB-96,02-JUN-99
   206209579 29-APR-82,29-APR-82

SQL>

Другие способы продемонстрированы в статье Тима здесь.

person Lalit Kumar B    schedule 24.02.2015
comment
Downvoter, не могли бы вы сказать причину понижения? На всякий случай добавил примечание. - person Lalit Kumar B; 24.02.2015
comment
Большое спасибо, Лалит Кумар Б., - person Anand Yadav; 27.02.2015