Jak już kilka razy nadmieniałem, wymyślanie tytułów nie jest moją najsilniejszą stroną. Nie szkodzi, zaraz wszystko się wyjaśni (mam nadzieję…)
Wyobraźmy sobie następujący scenariusz: mamy w bazie danych tabelę procedur (zabiegów) przeprowadzanych na pacjentach. Jeden wiersz na procedurę, o tak:
Naszym zadaniem jest ustalenie jakie kombinacje procedur były przeprowadzone na poszczególnych pacjentach, oraz ilu pacjentów przypada na każdą kombinację.
W pierwszym podejściu obyty z tematem programista napisze coś w stylu:
WITH Kombinacje AS ( SELECT PACJENT_ID, STRING_AGG(KOD_PROCEDURY, '-') AS Kombinacja FROM Procedury GROUP BY PACJENT_ID ) SELECT Kombinacja, COUNT(DISTINCT PACJENT_ID) AS IluPacjentow FROM Kombinacje GROUP BY Kombinacja;
Podejście zasadniczo poprawne (na końcu większość zapewne doda jeszcze ORDER BY 2 DESC
, żeby te najczęstsze kombinacje pokazały się na samej górze), ale jest tu jeden haczyk: otóż operator STRING_AGG
nie dba o kolejność łączonych tekstów i może się okazać, że na wyjściu dostaniemy:
DBB-ACX-HLD,1
DBB-HLD-ACX,1
Innymi słowy kombinację zabiegów ACX-DBB-HLD miało dwóch pacjentów (jedynka i czwórka), ale ponieważ operator STRING_AGG nie dba o kolejność łączonych elementów, na wyjściu dostaniemy informację nieco przekłamaną.
Cóż począć?
Rozwiązanie jest nieoczywiste, choć dość proste. Otóż operator STRING_AGG akceptuje następującą składnię:
STRING_AGG(...) WITHIN GROUP(ORDER BY kolumna)
A więc czwartą linię naszego zapytania należy napisać tak:
STRING_AGG(KOD_PROCEDURY, '-') WITHIN GROUP (ORDER BY KOD_PROCEDURY) AS Kombinacja
I teraz okaże się, że na wyjściu dostaniemy:
ACX-DBB-HLD,2
Piszę o tym, bo ostatnio mnie ten temat ugryzł w ramach orki na korporacyjnym ugorze i byłbym poległ, gdyby nie to właśnie rozwiązanie.
Jeżeli chcesz do komentarza wstawić kod, użyj składni:
[code]
tutaj wstaw swój kod
[/code]
Jeżeli zrobisz literówkę lub zmienisz zdanie, możesz edytować komentarz po jego zatwierdzeniu.