2016-07-13 2 views
0

Я пишу инструкцию ORACLE select с LISTAGG. Он работает, но когда я проверял данные, я видел дубликаты вроде 1: 1,1: 1,2: 2,2: 2.Oracle LISTAGG case возвращает отдельные значения

Я подтвердил, что база данных имеет дубликат. Запрос предназначен для двух таблиц в отношениях от одного до многих. Ниже приведен фрагмент моего запроса, но я изменил имена столбцов и т. Д.

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

Благодаря

SELECT Table1.PERSON_ID, 
     Table1.FIRST_NAME, 
     Table1.MIDDLE_NAME, 
     Table1.LAST_NAME, 

LISTAGG(case 
     when Table2.DESCRIPTION = '1' then '1:1' 
     when Table2.DESCRIPTION = '2' then '2:2' 
     when Table2.DESCRIPTION = '3' then '3:3' 
     when Table2.DESCRIPTION = '4' then '4:4' 
     when Table2.DESCRIPTION = '5' then '5:5' 
     when Table2.DESCRIPTION = '6' then '6:6' 
     when Table2.DESCRIPTION = '7' then '7:7' 
     when Table2.DESCRIPTION = '8' then '8:8' 
     when Table2.DESCRIPTION = '9' then '9:9' 


     else '' 

end, ',') 
WITHIN GROUP (ORDER BY Table2.DESCRIPTION) 

FROM Table1 
LEFT JOIN Table2 

ON Table2.PERSON_ID = Table1.PERSON_ID 
GROUP BY Table1.PERSON_ID,Table1.FIRST_NAME,Table1.MIDDLE_NAME, Table1.LAST_NAME 

ответ

0

Предполагая Table2 имеет PERSON_ID в качестве внешнего ключа, указывающей Table1, что вам нужно сделать, это заменить

FROM Table1 
LEFT JOIN Table2 
ON Table2.PERSON_ID = Table1.PERSON_ID 

с

FROM Table1 
LEFT JOIN 
(SELECT DISTINCT PERSON_ID, DESCRIPTION FROM Table2) T2 
ON T2.PERSON_ID = Table1.PERSON_ID 

, а затем изменить Table2 к T2LISTAGG() в (в том числе в пункте WITHIN GROUP (ORDER BY ...)!)

+0

Спасибо, mathguy, ваш ответ сработал !!!! – John

2

В Oracle, вам нужно сделать DISTINCT в подзапрос:

SELECT PERSON_ID, FIRST_NAME, MIDDLE_NAME, LAST_NAME, 
     LISTAGG(val, ',') WITHIN GROUP (ORDER BY DESCRIPTION) 
FROM (SELECT DISTINCT Table1.PERSON_ID, Table1.FIRST_NAME, Table1.MIDDLE_NAME, Table1.LAST_NAME, Table2.Description 
      (case when Table2.DESCRIPTION = '1' then '1:1' 
        when Table2.DESCRIPTION = '2' then '2:2' 
        when Table2.DESCRIPTION = '3' then '3:3' 
        when Table2.DESCRIPTION = '4' then '4:4' 
        when Table2.DESCRIPTION = '5' then '5:5' 
        when Table2.DESCRIPTION = '6' then '6:6' 
        when Table2.DESCRIPTION = '7' then '7:7' 
        when Table2.DESCRIPTION = '8' then '8:8' 
        when Table2.DESCRIPTION = '9' then '9:9' 
        else '' 
       end) as val 
     FROM Table1 LEFT JOIN 
      Table2 
      ON Table2.PERSON_ID = Table1.PERSON_ID 
    ) 
GROUP BY PERSON_ID, FIRST_NAME, MIDDLE_NAME, LAST_NAME; 
+0

правлю мой запрос в указанный Вами. Я получаю следующую ошибку: ORA-00904: «DBName». «VIEW». «ОПИСАНИЕ»: неверный идентификатор. В запрошенном запросе DBNAME.VIEW - «Таблица2». Попытка выяснить, как это исправить. – John

+0

В Oracle вы не можете ссылаться на имя таблицы, если она вложена более чем на один уровень во внешнем запросе. Здесь Table2 появляется во внутреннем подзапросе (соединение), он не отображается в среднем подзапросе и используется во внешнем запросе. Чтобы сохранить его, среднему запросу должно быть присвоено имя, и это имя будет использоваться во внешнем запросе. Или просто скажите 'ОПИСАНИЕ' в' ORDER BY'. НО: Это решение не имеет большого смысла. 'SELECT DISTINCT' должно быть сделано на' Table2' перед соединением, а не на результате соединения. Просто исправьте его, как предложено, и сравните EXECUTE PLAN для двух предлагаемых решений. – mathguy

+0

@John. , , Внутренний запрос просто должен вернуть 'ОПИСАНИЕ'. –

Смежные вопросы