June 8, 2020 at 7:49 pm
Hi,
Please help me sort a comma separated column in the database table .
Create Table #CommaSeparatedString
(
ID INT,
Title nvarchar(10),
StringValue nvarchar(500)
)
INSERT INTO #CommaSeparatedString (ID,Title,StringValue)
SELECT 1,'Test1','EUR HQ,EME HQ,KSA HQ,NME HQ'
UNION ALL
SELECT 2,'Test2','LAN HQ,Colombia,Peru'
UNION ALL
SELECT 3,'Test3','NAO HQ,Trinidad and Tobago,Bermuda,Guyana,Suriname'
SELECT * FROM #CommaSeparatedString
-- Desired Result
SELECT 1 AS INT,'Test1' AS Title,'EME HQ,EUR HQ,KSA HQ,NME HQ'
UNION ALL
SELECT 2 AS INT,'Test2' AS Title,'Colombia,LAN HQ,Peru'
UNION ALL
SELECT 3 AS INT,'Test3' AS Title,'Bermuda,Guyana,NAO HQ,Suriname,Trinidad and Tobago'
June 8, 2020 at 8:00 pm
Ummm... why does KSA come first in #1 results?
--Jeff Moden
Change is inevitable... Change for the better is not.
June 8, 2020 at 8:05 pm
Sorry, it was my mistake . Should be 'EME HQ,EUR HQ,KSA HQNME HQ'
June 8, 2020 at 8:11 pm
Possibly something like this:
SELECT *
FROM #CommaSeparatedString css;
WITH ordered
AS (SELECT css.ID
,NewValue = STRING_AGG(ss.value, ',') WITHIN GROUP(ORDER BY ss.value)
FROM #CommaSeparatedString css
CROSS APPLY STRING_SPLIT(css.StringValue, ',') ss
GROUP BY css.ID)
UPDATE css
SET css.StringValue = o.NewValue
FROM #CommaSeparatedString css
JOIN ordered o
ON o.ID = css.ID;
SELECT *
FROM #CommaSeparatedString css;
The absence of evidence is not evidence of absence
- Martin Rees
The absence of consumable DDL, sample data and desired results is, however, evidence of the absence of my response
- Phil Parkin
June 8, 2020 at 8:13 pm
Oh dear, you have 2016 – STRING_AGG() does not work there, apologies.
Note also that your original code does not run – the column widths are not of sufficient size.
The absence of evidence is not evidence of absence
- Martin Rees
The absence of consumable DDL, sample data and desired results is, however, evidence of the absence of my response
- Phil Parkin
June 8, 2020 at 8:18 pm
I just corrected the data size. Thanks for pointing that out.
June 8, 2020 at 9:02 pm
Since you are on 2016 and you don't have access to STRING_AGG, you can still use FOR XML.
Select Distinct
ss.ID
, ss.Title
, SortedString = stuff((Select ',' + f.SortedValue
From (Select SortedValue = s.value
From #CommaSeparatedString css
Cross Apply string_split(css.StringValue, ',') s
Where css.ID = ss.ID
) As f
Order By f.SortedValue
For xml Path(''), Type).value('.', 'nvarchar(500)'), 1, 1, '')
From #CommaSeparatedString ss;
You may need to look at using a specific collation for the sort - depends on the collation of the data in the nvarchar column (if you don't actually use unicode data then it should be varchar). If you do actually have unicode data - but do not have special characters in the data that need to be encoded in XML you can remove the 'Type' declaration which will eliminate the XML reader in the plan.
Jeffrey Williams
“We are all faced with a series of great opportunities brilliantly disguised as impossible situations.”
― Charles R. Swindoll
How to post questions to get better answers faster
Managing Transaction Logs
June 8, 2020 at 10:21 pm
Is there any chance you could take the time to read a book on basic SQL and RDBMS? By definition, a table must have a key; this is not an option! Likewise, a key cannot be null. There is also no such creature as a generic "id"; it has to be the identifier of something in particular. Next, we don't like having redundant keys. So all you posted is garbage that is is completely non-relational. What you wanted to post was more like this:
CREATE TABLE CommaSeparatedStrings
(string_name VARCHAR(10) NOT NULL PRIMARY KEY,
string_value VARCHAR(500) NOT NULL);
It gets worse. Why are you using the old Sybase syntax for insertion statements? For a few decades, the ANSI/ISO standard syntax has been like this:
INSERT INTO CommaSeparatedStrings -- GARBAGE!
VALUES
('Test1', 'EUR HQ, EME HQ, KSA HQ, NME HQ'), -- not 1NF
('Test2', 'LAN HQ, Colombia, Peru'),
('Test3', 'NAO HQ, Trinidad and Tobago, Bermuda, Guyana, Suriname');
A reasonably smart SQL compiler can optimize this table-building syntax because it is a single statement.
But what you've missed completely. Is the whole concept of first normal form (1NF), which is, the very foundation of RDBMS. The values in the columns of a table are atomic values, not repeated groups. This is generally covered in the first few chapters of any book on SQL or RDBMS (usually before the fifth chapter).
CREATE TABLE SomethingStrings
(string_name VARCHAR(10) NOT NULL,
string_value VARCHAR(500) NOT NULL,
PRIMARY KEY (string_name, string_value));
INSERT INTO Some_Strings
VALUES
('Test1', 'EUR HQ’),
('Test1', ‘EME HQ’),
('Test1', ‘KSA HQ’),
('Test1', ‘NME HQ'),
('Test2', 'LAN HQ’),
('Test2', ‘Colombia’),
('Test2', ‘Peru'),
('Test3', 'NAO HQ'),
('Test3', ‘Trinidad and Tobago’),
('Test3', ‘Bermuda’),
('Test3', ‘Guyana'),
('Test3', ‘Suriname');
I've been teaching SQL for over 30 years. Why did you think that this was the right way to do RDBMS or write SQL?. What was your first programming language? Usually, people don't make random mistakes, but they mimic the syntax and semantics of the languages they know when they try to learn something new.
Please post DDL and follow ANSI/ISO standards when asking for help.
Viewing 8 posts - 1 through 7 (of 7 total)
You must be logged in to reply to this topic. Login to reply