TransWikia.com

How to use order by within the STUFF function and exclude specific values

Stack Overflow Asked by Thirdy Leon on November 7, 2021

How can I use order by within the STUFF and exclude specific value? Here’s my query.

SELECT ID, STUFF((
        SELECT ';' + t1.CTY
        FROM country_tbl t1
        WHERE t2.ID = t1.ID FOR XML PATH('')),1,1,'') AS aggregation
FROM master_tbl t2
WHERE t2.ID IN ('123456','123457')
GROUP BY ID;
ORDER BY T2.ID
t1
ID     Country
123456 England
123457 Canada

t2
ID     CTY
123456 England
123456 Japan
123456 France
123456 Canada
123457 England
123457 Japan
123457 France

Result
ID     CTY
123456 Canada;France;Japan    Except England (CTY Sorted A-Z)    
123457 England;France;Japan   No Exception (CTY Sorted A-Z) 

2 Answers

You can use an ORDER BY and WHERE clause in the subquery. Something like this:

SELECT ID,
       STUFF( (SELECT ';' + t1.CTY
               FROM country_tbl t1
               WHERE t2.ID = t1.ID AND
                     NOT (t1.id = '123456' AND t1.CTY = 'England')
               ORDER BY t1.CTY
               FOR XML PATH('')
              ), 1, 1, ''
            ) AS aggregation
FROM (SELECT DISTINCT id
      FROM master_tbl t2
      WHERE t2.ID IN ('123456','123457')
     ) t2
ORDER BY T2.ID;

I also changed the GROUP BY in the outer query to a SELECT DISTINCT to boost performance.

Answered by Gordon Linoff on November 7, 2021

If I understand you correctly, you want to list the cities in t2 except those that appear in t1 with the same ids, in an ascending order. If that's the case, then you're close, but not quite there.

First, create and populate sample tables (Please save us this step in your future questions):

DECLARE @t1 AS TABLE (
    [ID] int, 
    [Country] varchar(7)
);
    
INSERT INTO @t1 ([ID], [Country]) VALUES
(123456, 'England'),
(123457, 'Canada');


DECLARE @t2 AS TABLE (
    [ID] int, 
    [CTY] varchar(7)
);
    
INSERT INTO @t2 ([ID], [CTY]) VALUES
(123456, 'England'),
(123456, 'Japan'),
(123456, 'France'),
(123456, 'Canada'),
(123457, 'England'),
(123457, 'Japan'),
(123457, 'France');

The query:

SELECT DISTINCT Id,
        STUFF((
            SELECT ';' + t2.CTY
            FROM @t2 As t2
            LEFT JOIN @t1 As t1
                ON t2.Id = t1.Id
                AND t2.CTY = t1.Country
            WHERE t2.ID = t0.ID 
            AND t1.Id IS NULL
            ORDER BY t2.CTY
            FOR XML PATH('')),1,1,'') AS aggregation
FROM @t2 As t0

Results:

Id      aggregation
123456  Canada;France;Japan
123457  England;France;Japan

Answered by Zohar Peled on November 7, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP