blog.mgsxx.com
Програмиране
Не е толкова често, но редовно трябва да използвам SQL, за да обединя всички редове в селекция някъде по следния начин:
Проблемът е, че нито стандартният SQL, нито Oracle (доскоро) нямаха функция като CONCAT. Какво може да се направи?
Потребителска функция
Можете да напишете своя собствена PL/SQL обобщена функция. Не че изобщо не беше забавно, но кодът трябва да бъде надлежно надраскан.
Основният проблем при този подход е SQL обвързването с вашата база данни. Ако дадете своя SQL на някого, трябва да му дадете и функцията.
Оказва се, че Oracle има функция, наречена WM_CONCAT, която прави точно това, което трябва да направи:
Той дори поддържа DISTINCT. Това е добре, но тази функция не се поддържа официално от Oracle и СТРАШНИ ГРЪБОВЕ. Той може безшумно да върне NULL. Може би изведнъж (точно какво изведнъж, всичко е работило вчера, но днес планът се е променил) започне да дава грешки, например ORA-22922. Така че не използвайте тази функция!
Oracle 11g Release 2 най-накрая добави стандартна вградена агрегирана функция за обединяване: LISTAGG. Това е добре за всички: изрично е посочен редът на сортиране на стойностите, може да се посочи произволен разделител, работи с DISTINCT, може да се използва като аналитична функция.
Функцията има само два недостатъка. Първо, няма начин да се върне CLOB, а не VARCHAR2; следователно дължината на резултата е ограничена. WM_CONCAT, например, връща CLOB. Но този недостатък може дори да е предимство, тъй като такива дълги редове обикновено не са необходими и е грозно да се правят касти за пореден път. На второ място ... е, това е временен недостатък, но все пак уместен: не всички са преминали към най-новия Oracle.
LISTAGG има още един, редовно много досаден недостатък: DISTINCT не се поддържа. Това, което попречи на фиксирането на функцията, е загадка извън моето разбиране. Тъй като сортирането на стойностите е извършено, какви технически проблеми има при премахването на дубликати по пътя?
Какво да направите, трябва да се отървете от него. Една от опциите е опцията за подзаявка, описана по-долу, в която DISTINCT вече е направена. Досадно и не винаги възможно. Хората измислиха друг начин: премахване на дубликати с регулярни изрази. Ето пример от моята практика:
- Аналитични функции в Oracle - Аналитични функции в Oracle, oracle - Софтуерни продукти
- Обобщена функция от обобщена функция, Интерактивен урок за SQL
- Абажури за дизайн на подови лампи, функции, предимства и недостатъци, мерки за безопасност,
- Болничен асансьор (асансьор за болници) - модификации, специфичност на приложение, ПРОЕКТИВЕН СТРОЙ
- 10 идеи за лятна сватба