Począwszy od SQL Server 2017, możesz teraz wyświetlać wyniki zapytania jako listę. Oznacza to, że Twój zestaw wyników może być wyświetlany jako lista oddzielona przecinkami, lista oddzielona spacjami lub jakikolwiek inny separator, który wybierzesz.
Chociaż prawdą jest, że można było osiągnąć ten sam efekt przed SQL Server 2017, było to trochę kłopotliwe.
Transact-SQL ma teraz funkcję STRING_AGG()
funkcja, która łączy wartości wyrażeń łańcuchowych i umieszcza między nimi wartości separatora. Działa to w podobny sposób jak GROUP_CONCAT()
w MySQL funkcja.
Ten artykuł zawiera przykłady demonstrujące T-SQL STRING_AGG()
funkcja.
Przykładowe dane
Po pierwsze, oto kilka przykładowych danych.
SELECT TaskId, TaskName FROM Tasks;
Wynik:
TaskId TaskName ------ ------------ 1 Feed cats 2 Water dog 3 Feed garden 4 Paint carpet 5 Clean roof 6 Feed cats
Przykład – lista rozdzielana przecinkami
Więc możemy wziąć powyższe dane i użyć STRING_AGG()
funkcja, aby wyświetlić wszystkie nazwy zadań na jednej dużej liście oddzielonej przecinkami.
Tak:
SELECT STRING_AGG(TaskName, ', ') FROM Tasks;
Wynik:
Feed cats, Water dog, Feed garden, Paint carpet, Clean roof, Feed cats
Oczywiście niekoniecznie musi być oddzielony przecinkiem. Może być oddzielony dowolnym wyrażeniem NVARCHAR
lub VARCHAR
typ i może to być literał lub zmienna.
Przykład – łączenie kolumn
Możemy również użyć CONCAT()
funkcja łączenia dwóch pól razem, oddzielonych własnym separatorem.
Przykład:
SELECT STRING_AGG(CONCAT(TaskId, ') ', TaskName), ' ') FROM Tasks;
Wynik:
1) Feed cats 2) Water dog 3) Feed garden 4) Paint carpet 5) Clean roof 6) Feed cats
Przykład — wartości zerowe
Jeśli zestaw wyników zawiera wartości null, wartości te są ignorowane, a odpowiedni separator nie jest dodawany.
Jeśli to nie jest odpowiednie, możesz podać wartość dla wartości null, używając ISNULL()
funkcji i przekazując wartość, której chcesz użyć, za każdym razem, gdy napotkana zostanie wartość null. Dzięki temu zapewnisz, że nadal otrzymasz wynik, gdy wiersz zawiera wartość null.
Rozważmy na przykład następujące zapytanie i zestaw wyników:
SELECT TaskCode FROM Tasks;
Wynik:
TaskCode -------- cat123 null null pnt456 rof789 null
Widzimy, że w zestawie wyników znajdują się trzy wartości null.
Jeśli uruchomimy to przez STRING_AGG()
funkcja, otrzymujemy to:
SELECT STRING_AGG(TaskCode, ', ') FROM Tasks;
Wynik:
cat123, pnt456, rof789
Jeśli jednak użyjemy ISNULL()
funkcja zapewniająca symbol zastępczy dla dowolnych wartości null, otrzymujemy to:
SELECT STRING_AGG(ISNULL(TaskCode, 'N/A'), ', ') FROM Tasks;
Wynik:
cat123, N/A, N/A, pnt456, rof789, N/A
Przykład – pogrupowane wyniki
Możesz także użyć STRING_AGG()
funkcja podczas grupowania zestawu wyników. Na przykład możesz potrzebować listy albumów pogrupowanych według wykonawców.
Aby to zademonstrować, wyobraź sobie bazę danych z dwiema tabelami; Artists
i Albums
. Między tymi tabelami istnieje relacja jeden do wielu. Dla każdego wykonawcy może być wiele albumów.
Tak więc zwykłe zapytanie łączące obie tabele może wyglądać mniej więcej tak:
USE Music; SELECT ar.ArtistName, al.AlbumName FROM Artists ar INNER JOIN Albums al ON ar.ArtistId = al.ArtistId;
Wynik:
ArtistName AlbumName ------------------------- ------------------------ Iron Maiden Powerslave AC/DC Powerage Jim Reeves Singing Down the Lane Devin Townsend Ziltoid the Omniscient Devin Townsend Casualties of Cool Devin Townsend Epicloud Iron Maiden Somewhere in Time Iron Maiden Piece of Mind Iron Maiden Killers Iron Maiden No Prayer for the Dying The Script No Sound Without Silence Buddy Rich Big Swing Face Michael Learns to Rock Blue Night Michael Learns to Rock Eternity Michael Learns to Rock Scandinavia Tom Jones Long Lost Suitcase Tom Jones Praise and Blame Tom Jones Along Came Jones Allan Holdsworth All Night Wrong Allan Holdsworth The Sixteen Men of Tain
Jak widać, jeśli wykonawca ma więcej niż jeden album, nazwa artysty jest wyświetlana wielokrotnie – raz dla każdego albumu.
Ale możemy użyć STRING_AGG()
zmienić to tak, aby każdy wykonawca był wymieniany tylko raz, a po nim rozdzielona przecinkami lista albumów, które wydali:
USE Music; SELECT ar.ArtistName, STRING_AGG(al.AlbumName, ', ') FROM Artists ar INNER JOIN Albums al ON ar.ArtistId = al.ArtistId GROUP BY ArtistName;
Wynik:
ArtistName ------------------------- ------------------------------------------------------------------------------ AC/DC Powerage Allan Holdsworth All Night Wrong, The Sixteen Men of Tain Buddy Rich Big Swing Face Devin Townsend Ziltoid the Omniscient, Casualties of Cool, Epicloud Iron Maiden Powerslave, Somewhere in Time, Piece of Mind, Killers, No Prayer for the Dying Jim Reeves Singing Down the Lane Michael Learns to Rock Blue Night, Eternity, Scandinavia The Script No Sound Without Silence Tom Jones Long Lost Suitcase, Praise and Blame, Along Came Jones
Przykład – Porządkowanie wyników
Możesz użyć klauzuli order, aby uporządkować wyniki w połączonej grupie. Odbywa się to za pomocą WITHIN GROUP
klauzula. Korzystając z tej klauzuli, określasz zamówienie za pomocą ORDER BY
po którym następuje ASC
(rosnąco) lub DESC
(do schodzenia).
Przykład:
USE Music; SELECT ar.ArtistName, STRING_AGG(al.AlbumName, ', ') WITHIN GROUP (ORDER BY al.AlbumName DESC) FROM Artists ar INNER JOIN Albums al ON ar.ArtistId = al.ArtistId GROUP BY ArtistName;
Wynik:
ArtistName ------------------------- ------------------------------------------------------------------------------ AC/DC Powerage Allan Holdsworth The Sixteen Men of Tain, All Night Wrong Buddy Rich Big Swing Face Devin Townsend Ziltoid the Omniscient, Epicloud, Casualties of Cool Iron Maiden Somewhere in Time, Powerslave, Piece of Mind, No Prayer for the Dying, Killers Jim Reeves Singing Down the Lane Michael Learns to Rock Scandinavia, Eternity, Blue Night The Script No Sound Without Silence Tom Jones Praise and Blame, Long Lost Suitcase, Along Came Jones