До Oracle 11.2 я использовал пользовательскую агрегатную функцию для объединения столбца в строку. 11.2 Добавлена LISTAGG
функция, поэтому я пытаюсь использовать ее вместо этого. Моя проблема в том, что мне нужно устранить дубликаты в результатах и, похоже, я не могу этого сделать.
Вот пример.
CREATE TABLE ListAggTest AS (
SELECT rownum Num1, DECODE(rownum,1,'2',to_char(rownum)) Num2 FROM dual
CONNECT BY rownum<=6
);
SELECT * FROM ListAggTest;
NUM1 NUM2
---------- ---------------------
1 2
2 2 << Duplicate 2
3 3
4 4
5 5
6 6
То, что я хочу увидеть, это:
NUM1 NUM2S
---------- --------------------
1 2-3-4-5-6
2 2-3-4-5-6
3 2-3-4-5-6
4 2-3-4-5-6
5 2-3-4-5-6
6 2-3-4-5-6
Вот listagg
версия, которая близка, но не устраняет дубликаты.
SELECT Num1, listagg(Num2,'-') WITHIN GROUP (ORDER BY NULL) OVER () Num2s
FROM ListAggTest;
У меня есть решение, но это хуже, чем продолжать использовать пользовательскую функцию агрегирования.
oracle
oracle-11g-r2
aggregate
Ли Риффель
источник
источник
order by null
бытьorder by Num2
или я запутался?LISTAGG
продолжает отставать от Тома КайтаSTRAGG
, с которым это так же легко, какSTRAGG(DISTINCT ...)
Ответы:
Вы можете использовать регулярные выражения и
regexp_replace
удалить дубликаты после объединенияlistagg
:Это может быть проще, если Oracle поддерживает регулярные выражения или группы без захвата, но это не так .
Однако это решение позволяет избежать сканирования источника более одного раза.
DBFiddle здесь
источник
ORDER BY Num2
добивается, не правда ли (см. Здесь ). Или вы просто пытаетесь указать, что вам нужен ORDER BY, чтобы он работал?Насколько я вижу, с доступной на данный момент спецификацией языка это самый короткий путь для достижения того, чего вы хотите, если это необходимо сделать
listagg
.Каким было ваше решение, которое было хуже, чем нестандартное совокупное решение ?
источник
regexp
решение.Создайте пользовательскую агрегатную функцию для этого.
источник
Хотя это старый пост с принятым ответом, я думаю, что аналитическая функция LAG () хорошо работает в этом случае и заслуживает внимания:
Вот предложенный код:
Представленные ниже результаты соответствуют желанию ФП:
источник
Здесь было мое решение проблемы, которая, на мой взгляд, не так хороша, как использование нашей пользовательской агрегатной функции, которая уже существует.
источник
Вместо этого используйте WMSYS.WM_Concat.
Примечание. Эта функция недокументирована и не поддерживается. См. Https://forums.oracle.com/forums/message.jspa?messageID=4372641#4372641 .
источник
wm_concat
(даже если вы утверждаете, чтоwm_concat
проблема сама по себе не является причиной), у них будут основания для отказа в помощи, поскольку она не документирована и не поддерживается - не в случае, если вы используете пользовательский агрегат или какой-либо другой поддерживаемая функция.Вы также можете использовать оператор collect и затем написать собственную функцию pl / sql, которая преобразует коллекцию в строку.
Вы можете использовать
distinct
иorder by
вcollect
предложении, но если объединить, тоdistinct
не будет работать с 11.2.0.2 :(Обходной путь может быть подвыбор:
источник
Я создал это решение до того, как столкнулся с ListAgg, но все еще есть случаи, такие как проблема с дублирующимся значением, тогда этот инструмент полезен. Версия ниже имеет 4 аргумента, чтобы дать вам контроль над результатами.
Пояснение CLOBlist принимает в качестве параметра конструктор CLOBlistParam. CLOBlistParam имеет 4 аргумента
Пример использования
Ссылка на Gist ниже.
https://gist.github.com/peter-genesys/d203bfb3d88d5a5664a86ea6ee34eeca] 1
источник
Я знаю, что через некоторое время после первоначальной публикации, но это было первое место, которое я нашел после того, как Гуглинг нашел ответ на ту же проблему, и подумал, что кто-то еще, кто приземлился здесь, может быть рад найти краткий ответ, не основанный на слишком сложных запросах. или регулярные выражения
Это даст вам желаемый результат:
источник
Моя идея состоит в том, чтобы реализовать хранимую функцию следующим образом:
Извините, но в некоторых случаях (для очень большого набора) Oracle может вернуть эту ошибку:
но я думаю, что это хорошее начало;)
источник
LISTAGG
функции; они явно пытались выяснить, смогут ли они найти эффективный способ сделать это, используя встроеннуюLISTAGG
функцию, доступную с версии 11.2.Попробуй это:
Проблема с другими возможными решениями заключается в том, что нет корреляции между результатами для столбца 1 и столбца 2. Чтобы обойти это, внутренний запрос создает эту корреляцию, а затем удаляет дубликаты из этого набора результатов. Когда вы делаете listagg, набор результатов уже чист. проблема была больше связана с получением данных в удобном для использования формате.
источник
SQL был разработан как простой язык, очень близкий к английскому. Так почему бы тебе не написать это по-английски?
источник
источник
SELECT Num1, ( SELECT LISTAGG(Num2) WITHIN GROUP (ORDER BY Num2) FROM (SELECT distinct Num2 FROM listAggTest) ) Num2 FROM ListAggTest;
Наиболее эффективным решением является внутренний SELECT с GROUP BY, потому что DISTINCT и регулярные выражения работают медленно.
Это решение довольно простое - сначала вы получаете все уникальные комбинации num1 и num2 (внутренний SELECT), а затем вы получаете строку всех num2, сгруппированных по num1.
источник
SELECT * FROM ListAggTest;
.