Depiwotyzacja stringów pod kontrolą

https://xpil.eu/Yc2uX

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.

https://xpil.eu/Yc2uX

Leave a Comment

Komentarze mile widziane.

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.