Bạn đang gặp khó khăn khi làm việc với dữ liệu chuỗi trong SQL Server? Bài viết này sẽ hướng dẫn bạn cách sử dụng hai hàm mạnh mẽ STRING_AGG() và STRING_SPLIT() để nối và tách chuỗi một cách hiệu quả. Chúng ta cũng sẽ khám phá các giải pháp thay thế khi bạn làm việc với các phiên bản SQL Server cũ hơn. Đọc tiếp để làm chủ kỹ năng xử lý chuỗi trong SQL Server!
Trong nhiều trường hợp, dữ liệu trong cơ sở dữ liệu của bạn có thể được lưu trữ dưới dạng chuỗi phân cách bằng dấu phẩy. Ví dụ: một bảng `StudentMaster` có thể chứa một cột `Course` lưu trữ danh sách các `CourseId` mà một sinh viên đã đăng ký, được phân tách bằng dấu phẩy.
Yêu cầu đặt ra là bạn cần truy xuất thông tin chi tiết của sinh viên cùng với tên khóa học (CourseName) thay vì CourseId. Để thực hiện điều này, bạn cần nối các tên khóa học tương ứng từ bảng `CourseMaster` dựa trên danh sách CourseId trong bảng `StudentMaster`.
Nếu bạn đang sử dụng SQL Server 2017 trở lên, bạn có thể tận dụng hai hàm STRING_AGG() và STRING_SPLIT() để giải quyết vấn đề này một cách đơn giản.
Hàm STRING_SPLIT() cho phép bạn tách một chuỗi thành các phần tử dựa trên dấu phân cách. Hàm STRING_AGG() thực hiện ngược lại, nó nối các giá trị chuỗi từ nhiều hàng thành một chuỗi duy nhất, được phân tách bằng dấu phân cách bạn chỉ định.
Ví dụ, để lấy thông tin sinh viên cùng với danh sách tên khóa học, bạn có thể sử dụng truy vấn sau:
SELECT
s.ROLLNO,
s.NAME,
s.ADDRESS,
STRING_AGG(c.CourseName, ',') AS Course
FROM
dbo.StudentMaster AS s
CROSS APPLY
STRING_SPLIT(s.Course, ',') AS f
INNER JOIN
dbo.CourseMaster AS c
ON
f.value = c.CourseId
GROUP BY
s.ROLLNO, s.NAME, s.ADDRESS;
Trong truy vấn này, STRING_SPLIT() được sử dụng để tách chuỗi CourseId trong bảng `StudentMaster`. Sau đó, kết quả được nối với bảng `CourseMaster` để lấy tên khóa học tương ứng. Cuối cùng, STRING_AGG() nối các tên khóa học này lại thành một chuỗi duy nhất.
Nếu bạn đang sử dụng phiên bản SQL Server cũ hơn (trước 2017), bạn sẽ cần một hàm tự định nghĩa để tách chuỗi. Một giải pháp phổ biến là sử dụng hàm XML để tách chuỗi:
CREATE FUNCTION dbo.SplitStrings_XML
(
@List VARCHAR(MAX),
@Delimiter CHAR(1) = ','
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT Item = y.i.value('(./text())[1]', 'varchar(8000)')
FROM
(
SELECT x = CONVERT(XML, '' + REPLACE(@List, @Delimiter, '') + '').query('.')
) AS a CROSS APPLY x.nodes('i') AS y(i)
);
Sau khi tạo hàm này, bạn có thể sử dụng nó trong truy vấn của mình:
;WITH x AS (
SELECT
s.ROLLNO, s.Name, s.Address, c.CourseId, c.CourseName
FROM
dbo.StudentMaster AS s
CROSS APPLY
dbo.SplitStrings_XML(s.Course, default) AS f
INNER JOIN
dbo.CourseMaster AS c
ON
f.item = c.CourseId
)
SELECT
ROLLNO, Name, Address,
STUFF((
SELECT ',' + CourseName
FROM x AS x2
WHERE x2.ROLLNO = x.ROLLNO
ORDER BY CourseId
FOR XML PATH, TYPE
).value(N'.[1]',N'varchar(max)'),1,1,'')
FROM x
GROUP BY ROLLNO, Name, Address;
Truy vấn này sử dụng hàm `SplitStrings_XML` để tách chuỗi CourseId và sau đó nối các tên khóa học tương ứng.
Một cách khác, tuy nhiên kém hiệu quả hơn, là sử dụng toán tử LIKE trong một truy vấn con:
select
SM.ROLLNO,
SM.NAME,
SM.ADDRESS,
(
select
',' + CM.CourseName
from
dbo.CourseMaster as CM
where
',' + SM.Course + ',' like '%,' + CM.CourseId + ',%'
for xml path(''), type
).value('substring(text()[1], 2)', 'varchar(max)') as Course
from
dbo.StudentMaster as SM;
Mặc dù giải pháp này có thể hoạt động, nhưng nó thường chậm hơn và kém linh hoạt hơn so với việc sử dụng hàm tách chuỗi hoặc STRING_AGG() và STRING_SPLIT().
Các chuyên gia khuyên rằng, giải pháp tốt nhất là chuẩn hóa cơ sở dữ liệu của bạn. Thay vì lưu trữ dữ liệu chuỗi phân cách bằng dấu phẩy, bạn nên sử dụng một bảng liên kết (junction table) để thể hiện mối quan hệ nhiều-nhiều giữa sinh viên và khóa học. Điều này sẽ giúp bạn truy vấn dữ liệu một cách dễ dàng và hiệu quả hơn.
Bài viết này đã trình bày các phương pháp khác nhau để nối và tách chuỗi trong SQL Server, từ việc sử dụng các hàm tích hợp như STRING_AGG() và STRING_SPLIT() đến các giải pháp tự định nghĩa cho các phiên bản cũ hơn. Tuy nhiên, hãy luôn ghi nhớ rằng chuẩn hóa cơ sở dữ liệu là giải pháp tốt nhất về lâu dài. Hy vọng bài viết này hữu ích cho bạn!
Bài viết liên quan