Bắt đầu với SQL Server 2017, bây giờ bạn có thể làm cho kết quả truy vấn của mình xuất hiện dưới dạng danh sách. Điều này có nghĩa là bạn có thể để tập hợp kết quả của mình xuất hiện dưới dạng danh sách được phân tách bằng dấu phẩy, danh sách được phân tách bằng dấu cách hoặc bất kỳ dấu phân tách nào bạn chọn sử dụng.
Mặc dù đúng là bạn có thể đạt được hiệu quả tương tự trước SQL Server 2017, nhưng điều đó hơi khó hiểu.
Transact-SQL hiện có STRING_AGG()
hàm, nối các giá trị của biểu thức chuỗi và đặt các giá trị dấu phân cách giữa chúng. Điều này hoạt động theo cùng một cách với GROUP_CONCAT()
của MySQL chức năng.
Bài viết này cung cấp các ví dụ chứng minh T-SQL STRING_AGG()
chức năng.
Dữ liệu mẫu
Đầu tiên, đây là một số dữ liệu mẫu.
SELECT TaskId, TaskName FROM Tasks;
Kết quả:
TaskId TaskName ------ ------------ 1 Feed cats 2 Water dog 3 Feed garden 4 Paint carpet 5 Clean roof 6 Feed cats
Ví dụ - Danh sách được phân tách bằng dấu phẩy
Vì vậy, chúng tôi có thể lấy dữ liệu ở trên và sử dụng STRING_AGG()
chức năng liệt kê tất cả các tên nhiệm vụ trong một danh sách lớn được phân tách bằng dấu phẩy.
Như thế này:
SELECT STRING_AGG(TaskName, ', ') FROM Tasks;
Kết quả:
Feed cats, Water dog, Feed garden, Paint carpet, Clean roof, Feed cats
Tất nhiên, nó không nhất thiết phải được phân tách bằng dấu phẩy. Nó có thể được phân tách bằng bất kỳ biểu thức nào của NVARCHAR
hoặc VARCHAR
và nó có thể là một ký tự hoặc một biến.
Ví dụ - Kết hợp các cột
Chúng tôi cũng có thể sử dụng CONCAT()
có chức năng kết hợp hai trường với nhau, được phân tách bằng dấu phân cách riêng.
Ví dụ:
SELECT STRING_AGG(CONCAT(TaskId, ') ', TaskName), ' ') FROM Tasks;
Kết quả:
1) Feed cats 2) Water dog 3) Feed garden 4) Paint carpet 5) Clean roof 6) Feed cats
Ví dụ - Giá trị rỗng
Nếu tập hợp kết quả của bạn chứa các giá trị rỗng, các giá trị đó sẽ bị bỏ qua và dấu phân tách tương ứng sẽ không được thêm vào.
Nếu điều này không phù hợp, bạn có thể cung cấp giá trị cho các giá trị null bằng cách sử dụng ISNULL()
hàm và chuyển giá trị bạn muốn sử dụng bất cứ khi nào gặp phải giá trị rỗng. Làm điều này đảm bảo rằng bạn vẫn nhận được kết quả khi một hàng chứa giá trị null.
Ví dụ:hãy xem xét truy vấn và tập kết quả sau:
SELECT TaskCode FROM Tasks;
Kết quả:
TaskCode -------- cat123 null null pnt456 rof789 null
Chúng ta có thể thấy rằng có ba giá trị null trong tập kết quả.
Nếu chúng tôi chạy điều này thông qua STRING_AGG()
, chúng tôi nhận được cái này:
SELECT STRING_AGG(TaskCode, ', ') FROM Tasks;
Kết quả:
cat123, pnt456, rof789
Tuy nhiên, nếu chúng ta sử dụng ISNULL()
chức năng cung cấp trình giữ chỗ cho bất kỳ giá trị null nào, chúng tôi nhận được điều này:
SELECT STRING_AGG(ISNULL(TaskCode, 'N/A'), ', ') FROM Tasks;
Kết quả:
cat123, N/A, N/A, pnt456, rof789, N/A
Ví dụ - Kết quả được nhóm
Bạn cũng có thể sử dụng STRING_AGG()
chức năng khi nhóm tập hợp kết quả của bạn. Ví dụ:bạn có thể muốn một danh sách các album được nhóm theo nghệ sĩ.
Để chứng minh điều này, hãy tưởng tượng một cơ sở dữ liệu có hai bảng; Artists
và Albums
. Có một mối quan hệ một đến nhiều giữa các bảng này. Đối với mỗi nghệ sĩ, có thể có nhiều album.
Vì vậy, một truy vấn thông thường kết hợp cả hai bảng có thể trông giống như sau:
USE Music; SELECT ar.ArtistName, al.AlbumName FROM Artists ar INNER JOIN Albums al ON ar.ArtistId = al.ArtistId;
Kết quả:
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
Như bạn có thể thấy, nếu một nghệ sĩ có nhiều album, tên của nghệ sĩ sẽ được liệt kê nhiều lần - một lần cho mỗi album.
Nhưng chúng ta có thể sử dụng STRING_AGG()
để thay đổi điều này để chúng tôi liệt kê mỗi nghệ sĩ chỉ một lần, theo sau là danh sách các album được phân tách bằng dấu phẩy mà họ đã phát hành:
USE Music; SELECT ar.ArtistName, STRING_AGG(al.AlbumName, ', ') FROM Artists ar INNER JOIN Albums al ON ar.ArtistId = al.ArtistId GROUP BY ArtistName;
Kết quả:
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
Ví dụ - Sắp xếp các kết quả
Bạn có thể sử dụng mệnh đề thứ tự để sắp xếp các kết quả trong nhóm được nối. Điều này được thực hiện với WITHIN GROUP
mệnh đề. Khi sử dụng điều khoản này, bạn chỉ định đơn hàng với ORDER BY
theo sau là ASC
(để tăng dần) hoặc DESC
(để giảm dần).
Ví dụ:
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;
Kết quả:
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