CREATE TABLE Products (
sku INT PRIMARY KEY,
product_desc VARCHAR(35));
CREATE TABLE Departments (
department_nbr INT PRIMARY KEY,
department_title VARCHAR(35));
CREATE TABLE DepartmentProducts (
department_nbr INT
REFERENCES Departments (department_nbr),
sku INT
REFERENCES Products (sku),
PRIMARY KEY (department_nbr, sku));
INSERT INTO Products VALUES (1, 'Book');
INSERT INTO Products VALUES (2, 'Magazine');
INSERT INTO Products VALUES (3, 'DVD');
INSERT INTO Products VALUES (4, 'Video');
INSERT INTO Products VALUES (5, 'CD');
INSERT INTO Products VALUES (6, 'Map');
INSERT INTO Departments VALUES (1, 'Reference');
INSERT INTO Departments VALUES (2, 'Periodicals');
INSERT INTO Departments VALUES (3, 'Entertainment');
INSERT INTO DepartmentProducts VALUES (1, 1);
INSERT INTO DepartmentProducts VALUES (1, 6);
INSERT INTO DepartmentProducts VALUES (2, 2);
INSERT INTO DepartmentProducts VALUES (3, 3);
INSERT INTO DepartmentProducts VALUES (3, 4);
INSERT INTO DepartmentProducts VALUES (3, 5);
-- Using correlated subquery
SELECT D.department_nbr,
D.department_title,
STUFF((SELECT ',' + product_desc
FROM DepartmentProducts AS DP
JOIN Products AS P
ON P.sku = DP.sku
WHERE DP.department_nbr = D.department_nbr
ORDER BY product_desc
FOR XML PATH('')), 1, 1, '') AS product_list
FROM Departments AS D;
-- Using CROSS APPLY
SELECT D.department_nbr,
D.department_title,
STUFF(P.product_list, 1, 1, '') AS product_list
FROM Departments AS D
CROSS APPLY (SELECT ',' + product_desc
FROM DepartmentProducts AS DP
JOIN Products AS P
ON P.sku = DP.sku
WHERE DP.department_nbr = D.department_nbr
ORDER BY product_desc
FOR XML PATH('')) AS P (product_list);
-- Results
department_nbr department_title product_list
-------------- ---------------- ------------
1 Reference Book,Map
2 Periodicals Magazine
3 Entertainment CD,DVD,Video
While this method is often called the XML blackbox method, the explanation of this effect using FOR XML PATH is simple. Normally the PATH clause is used with input string that indicates the name of the wrapper element that will be created. However, using the PATH clause with empty string as input results in skipping the wrapper element generation. And since the content is retrieved as text it achieves the effect of concatenation.
Resources:
What's New in FOR XML in Microsoft SQL Server 2005
http://msdn2.microsoft.com/en-us/library/ms345137.aspx

1 comments:
Cheers, this post saved me hours.
Post a Comment