sql-servert-sqlstuff

T-SQL - using STUFF to concatenate grouped columns and removing duplicates


I have a table that looks like this:

EmailAddress: nvarchar(255)
MarketingEmailOptIn: nvarchar(50)
NewsletterOptIn: nvarchar(50)
ThoughtLeaderOptIn: nvarchar(50)

enter image description here

My SQL statement shown below takes the data above and concatenates the "Subscription Type" using a comma as the delimiter:

SELECT  
    EmailAddress,
    STUFF((SELECT ',' + 
              CASE
                 WHEN B.MarketingEmailOptIn = 'TRUE' THEN 'MarketingEmail' 
                 WHEN B.ThoughtLeaderOptIn = 'TRUE' THEN 'ThoughtLeader'
                 WHEN B.NewsletterOptIn = 'TRUE' THEN 'Newsletter'
              END
          FROM UK_AGT_AgentForms_TEST_DE B 
          WHERE ISNULL(B.EmailAddress, '') = ISNULL(A.EmailAddress, '')
          FOR XML PATH('')), 1, 2, '') AS Subscriptions
FROM
    UK_AGT_AgentForms_TEST_DE A
GROUP BY 
    EmailAddress 

Running this SQL produces the following output:

enter image description here

However notice that MarketingEmail is listed twice because the source table ALSO has it listed twice (1st and 2nd rows). I need to omit any duplicate detected, so that my resulting table would look like:

enter image description here

I'm pretty new to the STUFF keyword. I'm just kind of lost on how to detect duplicates at run time - any advice is appreciated. Thanks


Solution

  • Pewh. I had to play around with this one. Maybe not the perfect solution, but I think I was able to achieve what you are trying. It doesn't use the stuff function though. It just concats each string and then removes the last comma.

    SELECT EmailAddress, CASE WHEN LEN(Subscriptions) > 0 THEN LEFT(Subscriptions, LEN(Subscriptions) - 1) ELSE '' END AS Subscriptions
    FROM (
        SELECT EmailAddress, CONCAT(
                CASE WHEN SUM(CASE WHEN MarketingEmailOptIn = 'TRUE' THEN 1 ELSE 0 END) > 0 THEN 'MarketingEmail, ' ELSE '' END,
                CASE WHEN SUM(CASE WHEN NewsletterOptIn = 'TRUE' THEN 1 ELSE 0 END) > 0 THEN 'Newsletter, ' ELSE '' END,
                CASE WHEN SUM(CASE WHEN ThoughtLeaderOptIn = 'TRUE' THEN 1 ELSE 0 END) > 0 THEN 'ThoughLeader, ' ELSE '' END
            ) AS Subscriptions
        FROM UK_AGT_AgentForms_TEST_DE 
        GROUP BY EmailAddress
    ) AS a