Как использовать функцию Oracle LISTAGG с несколькими значениями? - PullRequest
0 голосов
/ 28 августа 2018

У меня есть таблица «ПУНКТЫ», как показано ниже:

ITEM_NO     ITEM_NAME   
1               Book   
2               Pen   
3               Sticky Notes   
4               Ink   
5               Corrector   
6               Ruler  

В другой таблице 'EMP_ITEMS' у меня есть следующее:

EMPLOYEE        ITEMS_LIST   
 John           1,2   
 Mikel          5   
 Sophia         2,3,6  
 William        3,4   
 Daniel         null   
 Michael        6  

Вывод должен быть таким:

EMPLOYEE        ITEMS_LIST      ITEM_NAME   
John            1,2             Book,Pen   
Mikel           5               Corrector   
Sophia          2,3,6           Pen,Sticky Notes,Ruler   
William         3,4             Sticky Notes,Ink   
Daniel          null            null   
Michael         6               Ruler

Я использовал следующий запрос:

SELECT e.EMPLOYEE,e.ITEMS_LIST, LISTAGG(i.ITEM_NAME, ',') WITHIN GROUP (ORDER BY i.ITEM_NAME) ITEM_DESC 
 FROM EMP_ITEMS e  
INNER JOIN ITEMS i ON i.ITEM_NO = e.ITEMS_LIST 
GROUP BY e.EMPLOYEE,e.ITEMS_LIST;

Но есть ошибка:

ORA-01722: неверный номер

1 Ответ

0 голосов
/ 28 августа 2018

Но есть ошибка: ORA-01722: invalid number

Это потому, что ваш ITEMS_LIST - это строка, состоящая из цифр и запятых, которая на самом деле не является списком чисел, и вы пытаетесь сравнить один номер элемента со списком элементов.

Вместо этого рассматривайте его как строку для поиска совпадений подстроки. Для этого вам необходимо заключить строки в символ разделителя и сравнить их, чтобы увидеть, является ли одна подстрока другой:

SQL Fiddle

Настройка схемы Oracle 11g R2 :

CREATE TABLE Items ( ITEM_NO, ITEM_NAME ) As
SELECT 1, 'Book' FROM DUAL UNION ALL
SELECT 2, 'Pen' FROM DUAL UNION ALL
SELECT 3, 'Sticky Notes' FROM DUAL UNION ALL
SELECT 4, 'Ink' FROM DUAL UNION ALL
SELECT 5, 'Corrector' FROM DUAL UNION ALL
SELECT 6, 'Ruler' FROM DUAL;

CREATE TABLE emp_items ( EMPLOYEE, ITEMS_LIST ) AS
SELECT 'John', '1,2' FROM DUAL UNION ALL
SELECT 'Mikel', '5' FROM DUAL UNION ALL
SELECT 'Sophia', '3,2,6' FROM DUAL UNION ALL
SELECT 'William', '3,4' FROM DUAL UNION ALL
SELECT 'Daniel', null FROM DUAL UNION ALL
SELECT 'Michael', '6' FROM DUAL;

Запрос 1 :

SELECT e.employee,
       e.items_list,
       LISTAGG( i.item_name, ',' )
         WITHIN GROUP (
           ORDER BY INSTR( ','||e.items_list||',', ','||i.item_no||',' )
         ) AS item_names
FROM   emp_items e
       LEFT OUTER JOIN
       items i
       ON ( ','||e.items_list||',' LIKE '%,'||i.item_no||',%' )
GROUP BY e.employee, e.items_list

Результаты

| EMPLOYEE | ITEMS_LIST |             ITEM_NAMES |
|----------|------------|------------------------|
|     John |        1,2 |               Book,Pen |
|    Mikel |          5 |              Corrector |
|   Daniel |     (null) |                 (null) |
|   Sophia |      3,2,6 | Sticky Notes,Pen,Ruler |
|  Michael |          6 |                  Ruler |
|  William |        3,4 |       Sticky Notes,Ink |
...