Как объединить строки в одно поле в oracle с запросом по нескольким таблицам

это в базе данных оракула. таким образом, использование listagg ....

У меня есть таблица клиентов и таблица активов. Мне нужно иметь возможность возвращать IP-адреса в таблице ресурсов, разделенные запятыми. у каждого клиента может быть от 2 до 30 (или около того) IP-адресов.

Ресурсы

cust_id   IP
ABCD      192.168.1.5
ABCD      192.168.1.6
ABCD      192.168.1.7
DEFG      192.168.10.1
DEFG      192.168.10.2

Клиенты

Cust_id    Cust_name
DEFG       My first customer
ABCD       My second Customer

Мне нужно вернуть это:

My First Customer    DEFG    192.168.10.1, 192.168.10.2
My second customer   ABCD    192.168.1.5, 192.168.1.6, 192.168.1.7

простой запрос соединения отлично работает для возврата отдельных строк:

select  
CUST_NAMES.CUST_ID as CUST_ID, CUST_NAMES.CUST_NAME, IP
 from CUST_NAMES
INNER JOIN ASSETS 
ON CUST_NAMES.CUST_ID = ASSETS.CUST_ID

listagg прекрасно работает с одним табличным запросом:

select ASSETS.CUST_ID, listagg(IP, ',') within group (order by ASSETS.CUST_ID) 
from ASSETS
INNER JOIN CUSTOMERS
ON CUSTOMERS.CUST_ID = ASSETS.CUST_ID
group by ASSETS.CUST_ID

Но когда я пытаюсь добавить имя клиента в свой запрос, он сообщает мне, что это не функция GROUP BY.

select CUSTOMERS.CUST_NAME, ASSETS.CUST_ID, listagg(IP, ',') within group (order by ASSETS.CUST_ID)
from ASSETS
INNER JOIN CUSTOMERS
ON CUSTOMERS.CUST_ID = ASSETS.CUST_ID
group by ASSETS.CUST_ID

@Alex, .... Надеюсь, ты слышал ШЛЕПОК у меня на лбу .....

user2145893 10.08.2018 16:09
1
1
24
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Все неагрегированные столбцы в списке выбора должны быть включены в предложение group by, поэтому вам также необходимо добавить CUSTOMERS.CUST_NAME к нему.

select CUSTOMERS.CUST_NAME, ASSETS.CUST_ID,
  listagg(IP, ',') within group (order by ASSETS.CUST_ID)
from ASSETS
INNER JOIN CUSTOMERS
ON CUSTOMERS.CUST_ID = ASSETS.CUST_ID
group by CUSTOMERS.CUST_NAME, ASSETS.CUST_ID

На самом деле это не имеет ничего общего с двумя задействованными таблицами.

Поскольку существует только один клиент (имя) для каждого идентификатора клиента (я полагаю), я не вижу причин просто не добавлять CUST_NAME в вашу GROUP BY:

select CUSTOMERS.CUST_NAME, ASSETS.CUST_ID, listagg(IP, ',') within group (order by ASSETS.CUST_ID)
 from ASSETS
INNER JOIN CUSTOMERS ON CUSTOMERS.CUST_ID = ASSETS.CUST_ID
group by ASSETS.CUST_ID, CUSTOMERS.CUST_NAME

Другие вопросы по теме