Attempting to concatenate multiple rows.. unexpected results
Issue:
I'm trying to return a list of contacts with a column containing all the parent item names concatenated together. Please don't bother telling me this violates 1st normal form, I already know. I've been trying to get this working for so long that it is probably some stupid mistake, but I need some help at this point.
Query:
SELECT C.ID, C.SequenceNumber, C.ContactType, C.GUID, C.ContactCategory, MAP.Parents, C.LastName, C.FirstName, C.CompanyName, C.Title, C.Email, C.Phone, C.MobilePhone, C.Fax, C.Comments, C.StandardConfirmation, C.Active FROM
(
SELECT ContactTypeMapping.Contact_GUID, STUFF( ( SELECT ','+ [NAME]
FROM ContactParents a
WHERE a.GUID =b.GUID
FOR XML PATH('')),1 ,1, '') Parents
FROM ContactParents b, ContactTypeMapping
WHERE ContactTypeMapping.Parent_GUID=b.GUID
) MAP
INNER JOIN
(
SELECT Contact.ID, Contact.GUID, Contact.SequenceNumber,
Contact.ContactType, Contact.ContactCategory, Contact.LastName, Contact.FirstName,
Contact.CompanyName, Contact.Title, Contact.Email, Contact.Phone,
Contact.MobilePhone, Contact.Fax, Contact.Comments, Contact.StandardConfirmation, Contact.Active
FROM Contact
)C
ON (MAP.Contact_GUID=C.GUID)
Current results:
ID SequenceNumber ContactType GUID ContactCategory Parents LastName FirstName CompanyName Title Email Phone MobilePhone Fax Comments StandardConfirmation Active
15 4 2 95A566D0-DB83-4853-9CB7-E6CF3B1FF814 0 AParent Beard Kirk NULL Business [email protected] 913-906-3333 NULL (913) 906-3434 NULL 0 1
15 4 2 95A566D0-DB83-4853-9CB7-E6CF3B1FF814 0 AnotherParent Beard Kirk NULL Business [email protected] 913-906-3333 NULL (913) 906-3434 NULL 0 1
Desired results:
15 4 2 95A566D0-DB83-4853-9CB7-E6CF3B1FF814 0 AParent,AnotherParent Beard Kirk NULL Business [email protected] 913-906-3333 NULL (913) 906-3434 NULL 0 1
Data:
ContactParents Table:
GUID NAME TYPE
C40A6F7E-F760-48D6-8BAF-E55EC7DC900D AParent Place
A651A0A3-5A50-45F1-AB4B-2B7FDCE9734C AnotherParent Place
ContactTypeMapping Table:
Contact_GUID Parent_GUID ParentTable
95A566D0-DB83-4853-9CB7-E6CF3B1FF814 C40A6F7E-F760-48D6-8BAF-E55EC7DC900D Place
95A566D0-DB83-4853-9CB7-E6CF3B1FF814 A651A0A3-5A50-45F1-AB4B-2B7FDCE9734C Place
Contact Table:
ID GUID SequenceNumber ContactType LastName FirstName Title Email Phone MobilePhone Fax Comments Active ContactCategory CompanyName StandardConfirmation
15 95A566D0-DB83-4853-9CB7-E6CF3B1FF814 4 2 Beard Kirk Business [email protected] 913-906-3333 NULL (913) 906-3434 NULL 1 0 NULL 0
Solution 1:
;WITH cp AS -- contact parents - initial join
(
SELECT cp.NAME, ctm.Parent_GUID
FROM ContactParents AS cp
INNER JOIN ContactTypeMapping AS ctm
ON cp.GUID = ctm.Contact_GUID
),
cm AS -- contact mapping with concatenated values
(
SELECT Parent_GUID, Parents = (
SELECT STUFF ((SELECT ','+ [NAME] FROM cp AS cp2
WHERE cp2.Parent_GUID = cp.Parent_GUID
FOR XML PATH(''),
TYPE).value(N'./text()[1]',N'nvarchar(max)'),1 ,1, '')
)
FROM cp GROUP BY Parent_GUID
)
SELECT c.[GUID], cm.Parents --, other columns from c
FROM Contact AS c
INNER JOIN cm
ON c.[GUID] = cm.Parent_GUID;
To demonstrate how I verified that this query returns the right results, here are the table variables I created locally, how I populated them, and a slightly different query that references the table variables:
DECLARE @ContactParents TABLE
(
[GUID] UNIQUEIDENTIFIER,
NAME VARCHAR(32),
[TYPE] VARCHAR(32)
);
INSERT @ContactParents VALUES
('C40A6F7E-F760-48D6-8BAF-E55EC7DC900D','AParent','Place'),
('A651A0A3-5A50-45F1-AB4B-2B7FDCE9734C','AnotherParent','Place');
DECLARE @ContactTypeMapping TABLE
(
Contact_GUID UNIQUEIDENTIFIER,
Parent_GUID UNIQUEIDENTIFIER,
ParentTable VARCHAR(32)
);
INSERT @ContactTypeMapping VALUES
('A651A0A3-5A50-45F1-AB4B-2B7FDCE9734C','95A566D0-DB83-4853-9CB7-E6CF3B1FF814','Place'),
('C40A6F7E-F760-48D6-8BAF-E55EC7DC900D','95A566D0-DB83-4853-9CB7-E6CF3B1FF814','Place');
DECLARE @Contact TABLE
(
ID INT,
[GUID] UNIQUEIDENTIFIER,
LastName VARCHAR(32),
FirstName VARCHAR(32)
--, other columns...
);
INSERT @Contact VALUES
(15, '95A566D0-DB83-4853-9CB7-E6CF3B1FF814', 'Beard', 'Kirk');
;WITH cp AS
(
SELECT cp.NAME, ctm.Parent_GUID
FROM @ContactParents AS cp
INNER JOIN @ContactTypeMapping AS ctm
ON cp.GUID = ctm.Contact_GUID
),
cm AS
(
SELECT Parent_GUID, Parents = (
SELECT STUFF ((SELECT ','+ [NAME] FROM cp AS cp2
WHERE cp2.Parent_GUID = cp.Parent_GUID
FOR XML PATH('')),1 ,1, '')
)
FROM cp
GROUP BY Parent_GUID
)
SELECT c.[GUID], cm.Parents --, other columns from c
FROM @Contact AS c
INNER JOIN cm
ON c.[GUID] = cm.Parent_GUID;
Results
GUID Parents
95A566D0-DB83-4853-9CB7-E6CF3B1FF814 AParent,AnotherParent