Precise sort order of records that were found in a IN split function in SQL Server
up vote
0
down vote
favorite
I need to return records that I send to a stored procedure in a comma-separated string - like this:
@PMID = 29573145,24106086,20513766,24326307
I have a stored procedure that pulls records such as
SELECT
data,
PMID
FROM
[dbo].[ADMIN_Publication_JSON]
WHERE
PMID IN (SELECT DATA FROM dbo.Split(@PMID, ','))
The problem that I am having is that the return record set is random and I need it precise because my end user could change the order and the records need to be displayed in that order which would change the order in the comma string. Is this possible or do I need to totally change the way I pull the data? Thanks
sql sql-server stored-procedures sql-server-2014 sql-server-2016
add a comment |
up vote
0
down vote
favorite
I need to return records that I send to a stored procedure in a comma-separated string - like this:
@PMID = 29573145,24106086,20513766,24326307
I have a stored procedure that pulls records such as
SELECT
data,
PMID
FROM
[dbo].[ADMIN_Publication_JSON]
WHERE
PMID IN (SELECT DATA FROM dbo.Split(@PMID, ','))
The problem that I am having is that the return record set is random and I need it precise because my end user could change the order and the records need to be displayed in that order which would change the order in the comma string. Is this possible or do I need to totally change the way I pull the data? Thanks
sql sql-server stored-procedures sql-server-2014 sql-server-2016
Currently 2016 but I have access to 2012 also
– user1314159
Nov 10 at 20:45
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I need to return records that I send to a stored procedure in a comma-separated string - like this:
@PMID = 29573145,24106086,20513766,24326307
I have a stored procedure that pulls records such as
SELECT
data,
PMID
FROM
[dbo].[ADMIN_Publication_JSON]
WHERE
PMID IN (SELECT DATA FROM dbo.Split(@PMID, ','))
The problem that I am having is that the return record set is random and I need it precise because my end user could change the order and the records need to be displayed in that order which would change the order in the comma string. Is this possible or do I need to totally change the way I pull the data? Thanks
sql sql-server stored-procedures sql-server-2014 sql-server-2016
I need to return records that I send to a stored procedure in a comma-separated string - like this:
@PMID = 29573145,24106086,20513766,24326307
I have a stored procedure that pulls records such as
SELECT
data,
PMID
FROM
[dbo].[ADMIN_Publication_JSON]
WHERE
PMID IN (SELECT DATA FROM dbo.Split(@PMID, ','))
The problem that I am having is that the return record set is random and I need it precise because my end user could change the order and the records need to be displayed in that order which would change the order in the comma string. Is this possible or do I need to totally change the way I pull the data? Thanks
sql sql-server stored-procedures sql-server-2014 sql-server-2016
sql sql-server stored-procedures sql-server-2014 sql-server-2016
edited Nov 10 at 21:01
marc_s
565k12610921245
565k12610921245
asked Nov 10 at 20:30
user1314159
197110
197110
Currently 2016 but I have access to 2012 also
– user1314159
Nov 10 at 20:45
add a comment |
Currently 2016 but I have access to 2012 also
– user1314159
Nov 10 at 20:45
Currently 2016 but I have access to 2012 also
– user1314159
Nov 10 at 20:45
Currently 2016 but I have access to 2012 also
– user1314159
Nov 10 at 20:45
add a comment |
3 Answers
3
active
oldest
votes
up vote
5
down vote
accepted
You can use a window function like
Select T1.data,
T1.PMID
FROM [dbo].[ADMIN_Publication_JSON] T1 INNER JOIN
(SELECT Data,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) RN
FROMdbo.Split(@PMID,',')
) T2 ON T1.PMID = T2.Data
ORDER BY T2.RN;
Here is a little sample:
CREATE TABLE T(
ID INT,
SomeValue VARCHAR(45)
);
INSERT INTO T VALUES
(1, 'One'),
(2, 'Two'),
(3, 'Three'),
(4, 'Four'),
(5, 'Five');
DECLARE @IDs VARCHAR(200) = '3,5,2';
SELECT T.*
FROM T INNER JOIN
(SELECT Value,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) Seq
FROM STRING_SPLIT(@Ids, ',') --instead of your function
) TT
ON T.ID = TT.Value
ORDER BY TT.Seq;
Live Demo
How can I use that with a [FN_ListToTable] ?
– user1314159
Nov 10 at 21:16
stackoverflow.com/questions/878833/…
– user1314159
Nov 10 at 21:17
I think I post the first query for you @user1314159 and add extra samples to make it clear.
– Sami
Nov 10 at 21:19
Fantastic-- Thanks
– user1314159
Nov 10 at 21:24
I dont think we needROW_NUMBER()
– Nikhil Vartak
Nov 10 at 21:30
|
show 3 more comments
up vote
0
down vote
Split
method does not sort the Data
column that means simple join with its result can do the trick. You don't need ROW_NUMBER() or any sorting effort here. Have a temp table store Split
s result and LEFT JOIN
the two. This works for me.
CREATE TABLE #Input (PMID varchar(10))
INSERT INTO #Input SELECT Data FROM dbo.Split(@PMID, ',')
SELECT
jsn.*
FROM
#Input spl INNER JOIN ADMIN_Publication_JSON jsn on spl.PMID = jsn.PMID
Output: Returns the set in the order passed in @PMID
What if we change it toADMIN_Publication_JSON jsn INNER JOIN #Input spl on spl.PMID = jsn.PMID
? Does it works? and why we need to use a TempTable (create it and insert the data) while we can just use a window function?
– Sami
Nov 10 at 21:40
No it will not because in that case it will take up the records' order fromADMIN_Publication_JSON
table. What's the issue withLEFT JOIN
if that gives simpler query and desired output order. You can filter outnull
records from result if that worries you. What's say?
– Nikhil Vartak
Nov 10 at 21:46
I did not say my answer is better. These are just different possible ways of doing what OP needs.
– Nikhil Vartak
Nov 10 at 21:49
add a comment |
up vote
-1
down vote
I'm sorry to say but the currently accepted answer (by Sami) is wrong.
The problem with this answer is that it use ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
to get the order of the items in the comma delimited string, but since the order by
is done on select null
, what actually happens is that the row_number
will assign the numbers in an arbitrary order - that may or may not match the order of the strings in the source string.
If your split UDF returns a table with two columns, where one contains the substring and the other contains it's index, like Jeff Moden's DelimitedSplit8K, then simply use the ItemNumber
(or equivalent) column for the order by
. If it only returns a single column containing the substrings, you can use this a nice trick I've learned from Aaron Bertrand's Solve old problems with SQL Server’s new STRING_AGG and STRING_SPLIT functions - it will guarantee to return the correct order of the substrings as long as they are unique.
A simple change on Sami's answer will give you correct results as long as the substrings are unique within the comma delimited string - Instead of ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
, use CHARINDEX(',' + Value + ',', ',' + @Ids + ',')
, which will return the index of each substring inside the comma delimited string:
CREATE TABLE T(
ID INT,
SomeValue VARCHAR(45)
);
INSERT INTO T VALUES
(1, 'One'),
(2, 'Two'),
(3, 'Three'),
(4, 'Four'),
(5, 'Five');
DECLARE @IDs VARCHAR(200) = '3,5,2';
SELECT T.*
FROM T
INNER JOIN
(SELECT Value,
CHARINDEX(',' + Value + ',', ',' + @Ids + ',') AS Seq
FROM STRING_SPLIT(@Ids, ',') --instead of your function
) TT
ON T.ID = TT.Value
ORDER BY TT.Seq;
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
accepted
You can use a window function like
Select T1.data,
T1.PMID
FROM [dbo].[ADMIN_Publication_JSON] T1 INNER JOIN
(SELECT Data,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) RN
FROMdbo.Split(@PMID,',')
) T2 ON T1.PMID = T2.Data
ORDER BY T2.RN;
Here is a little sample:
CREATE TABLE T(
ID INT,
SomeValue VARCHAR(45)
);
INSERT INTO T VALUES
(1, 'One'),
(2, 'Two'),
(3, 'Three'),
(4, 'Four'),
(5, 'Five');
DECLARE @IDs VARCHAR(200) = '3,5,2';
SELECT T.*
FROM T INNER JOIN
(SELECT Value,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) Seq
FROM STRING_SPLIT(@Ids, ',') --instead of your function
) TT
ON T.ID = TT.Value
ORDER BY TT.Seq;
Live Demo
How can I use that with a [FN_ListToTable] ?
– user1314159
Nov 10 at 21:16
stackoverflow.com/questions/878833/…
– user1314159
Nov 10 at 21:17
I think I post the first query for you @user1314159 and add extra samples to make it clear.
– Sami
Nov 10 at 21:19
Fantastic-- Thanks
– user1314159
Nov 10 at 21:24
I dont think we needROW_NUMBER()
– Nikhil Vartak
Nov 10 at 21:30
|
show 3 more comments
up vote
5
down vote
accepted
You can use a window function like
Select T1.data,
T1.PMID
FROM [dbo].[ADMIN_Publication_JSON] T1 INNER JOIN
(SELECT Data,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) RN
FROMdbo.Split(@PMID,',')
) T2 ON T1.PMID = T2.Data
ORDER BY T2.RN;
Here is a little sample:
CREATE TABLE T(
ID INT,
SomeValue VARCHAR(45)
);
INSERT INTO T VALUES
(1, 'One'),
(2, 'Two'),
(3, 'Three'),
(4, 'Four'),
(5, 'Five');
DECLARE @IDs VARCHAR(200) = '3,5,2';
SELECT T.*
FROM T INNER JOIN
(SELECT Value,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) Seq
FROM STRING_SPLIT(@Ids, ',') --instead of your function
) TT
ON T.ID = TT.Value
ORDER BY TT.Seq;
Live Demo
How can I use that with a [FN_ListToTable] ?
– user1314159
Nov 10 at 21:16
stackoverflow.com/questions/878833/…
– user1314159
Nov 10 at 21:17
I think I post the first query for you @user1314159 and add extra samples to make it clear.
– Sami
Nov 10 at 21:19
Fantastic-- Thanks
– user1314159
Nov 10 at 21:24
I dont think we needROW_NUMBER()
– Nikhil Vartak
Nov 10 at 21:30
|
show 3 more comments
up vote
5
down vote
accepted
up vote
5
down vote
accepted
You can use a window function like
Select T1.data,
T1.PMID
FROM [dbo].[ADMIN_Publication_JSON] T1 INNER JOIN
(SELECT Data,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) RN
FROMdbo.Split(@PMID,',')
) T2 ON T1.PMID = T2.Data
ORDER BY T2.RN;
Here is a little sample:
CREATE TABLE T(
ID INT,
SomeValue VARCHAR(45)
);
INSERT INTO T VALUES
(1, 'One'),
(2, 'Two'),
(3, 'Three'),
(4, 'Four'),
(5, 'Five');
DECLARE @IDs VARCHAR(200) = '3,5,2';
SELECT T.*
FROM T INNER JOIN
(SELECT Value,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) Seq
FROM STRING_SPLIT(@Ids, ',') --instead of your function
) TT
ON T.ID = TT.Value
ORDER BY TT.Seq;
Live Demo
You can use a window function like
Select T1.data,
T1.PMID
FROM [dbo].[ADMIN_Publication_JSON] T1 INNER JOIN
(SELECT Data,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) RN
FROMdbo.Split(@PMID,',')
) T2 ON T1.PMID = T2.Data
ORDER BY T2.RN;
Here is a little sample:
CREATE TABLE T(
ID INT,
SomeValue VARCHAR(45)
);
INSERT INTO T VALUES
(1, 'One'),
(2, 'Two'),
(3, 'Three'),
(4, 'Four'),
(5, 'Five');
DECLARE @IDs VARCHAR(200) = '3,5,2';
SELECT T.*
FROM T INNER JOIN
(SELECT Value,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) Seq
FROM STRING_SPLIT(@Ids, ',') --instead of your function
) TT
ON T.ID = TT.Value
ORDER BY TT.Seq;
Live Demo
edited Nov 10 at 21:04
answered Nov 10 at 20:59
Sami
6,33031038
6,33031038
How can I use that with a [FN_ListToTable] ?
– user1314159
Nov 10 at 21:16
stackoverflow.com/questions/878833/…
– user1314159
Nov 10 at 21:17
I think I post the first query for you @user1314159 and add extra samples to make it clear.
– Sami
Nov 10 at 21:19
Fantastic-- Thanks
– user1314159
Nov 10 at 21:24
I dont think we needROW_NUMBER()
– Nikhil Vartak
Nov 10 at 21:30
|
show 3 more comments
How can I use that with a [FN_ListToTable] ?
– user1314159
Nov 10 at 21:16
stackoverflow.com/questions/878833/…
– user1314159
Nov 10 at 21:17
I think I post the first query for you @user1314159 and add extra samples to make it clear.
– Sami
Nov 10 at 21:19
Fantastic-- Thanks
– user1314159
Nov 10 at 21:24
I dont think we needROW_NUMBER()
– Nikhil Vartak
Nov 10 at 21:30
How can I use that with a [FN_ListToTable] ?
– user1314159
Nov 10 at 21:16
How can I use that with a [FN_ListToTable] ?
– user1314159
Nov 10 at 21:16
stackoverflow.com/questions/878833/…
– user1314159
Nov 10 at 21:17
stackoverflow.com/questions/878833/…
– user1314159
Nov 10 at 21:17
I think I post the first query for you @user1314159 and add extra samples to make it clear.
– Sami
Nov 10 at 21:19
I think I post the first query for you @user1314159 and add extra samples to make it clear.
– Sami
Nov 10 at 21:19
Fantastic-- Thanks
– user1314159
Nov 10 at 21:24
Fantastic-- Thanks
– user1314159
Nov 10 at 21:24
I dont think we need
ROW_NUMBER()
– Nikhil Vartak
Nov 10 at 21:30
I dont think we need
ROW_NUMBER()
– Nikhil Vartak
Nov 10 at 21:30
|
show 3 more comments
up vote
0
down vote
Split
method does not sort the Data
column that means simple join with its result can do the trick. You don't need ROW_NUMBER() or any sorting effort here. Have a temp table store Split
s result and LEFT JOIN
the two. This works for me.
CREATE TABLE #Input (PMID varchar(10))
INSERT INTO #Input SELECT Data FROM dbo.Split(@PMID, ',')
SELECT
jsn.*
FROM
#Input spl INNER JOIN ADMIN_Publication_JSON jsn on spl.PMID = jsn.PMID
Output: Returns the set in the order passed in @PMID
What if we change it toADMIN_Publication_JSON jsn INNER JOIN #Input spl on spl.PMID = jsn.PMID
? Does it works? and why we need to use a TempTable (create it and insert the data) while we can just use a window function?
– Sami
Nov 10 at 21:40
No it will not because in that case it will take up the records' order fromADMIN_Publication_JSON
table. What's the issue withLEFT JOIN
if that gives simpler query and desired output order. You can filter outnull
records from result if that worries you. What's say?
– Nikhil Vartak
Nov 10 at 21:46
I did not say my answer is better. These are just different possible ways of doing what OP needs.
– Nikhil Vartak
Nov 10 at 21:49
add a comment |
up vote
0
down vote
Split
method does not sort the Data
column that means simple join with its result can do the trick. You don't need ROW_NUMBER() or any sorting effort here. Have a temp table store Split
s result and LEFT JOIN
the two. This works for me.
CREATE TABLE #Input (PMID varchar(10))
INSERT INTO #Input SELECT Data FROM dbo.Split(@PMID, ',')
SELECT
jsn.*
FROM
#Input spl INNER JOIN ADMIN_Publication_JSON jsn on spl.PMID = jsn.PMID
Output: Returns the set in the order passed in @PMID
What if we change it toADMIN_Publication_JSON jsn INNER JOIN #Input spl on spl.PMID = jsn.PMID
? Does it works? and why we need to use a TempTable (create it and insert the data) while we can just use a window function?
– Sami
Nov 10 at 21:40
No it will not because in that case it will take up the records' order fromADMIN_Publication_JSON
table. What's the issue withLEFT JOIN
if that gives simpler query and desired output order. You can filter outnull
records from result if that worries you. What's say?
– Nikhil Vartak
Nov 10 at 21:46
I did not say my answer is better. These are just different possible ways of doing what OP needs.
– Nikhil Vartak
Nov 10 at 21:49
add a comment |
up vote
0
down vote
up vote
0
down vote
Split
method does not sort the Data
column that means simple join with its result can do the trick. You don't need ROW_NUMBER() or any sorting effort here. Have a temp table store Split
s result and LEFT JOIN
the two. This works for me.
CREATE TABLE #Input (PMID varchar(10))
INSERT INTO #Input SELECT Data FROM dbo.Split(@PMID, ',')
SELECT
jsn.*
FROM
#Input spl INNER JOIN ADMIN_Publication_JSON jsn on spl.PMID = jsn.PMID
Output: Returns the set in the order passed in @PMID
Split
method does not sort the Data
column that means simple join with its result can do the trick. You don't need ROW_NUMBER() or any sorting effort here. Have a temp table store Split
s result and LEFT JOIN
the two. This works for me.
CREATE TABLE #Input (PMID varchar(10))
INSERT INTO #Input SELECT Data FROM dbo.Split(@PMID, ',')
SELECT
jsn.*
FROM
#Input spl INNER JOIN ADMIN_Publication_JSON jsn on spl.PMID = jsn.PMID
Output: Returns the set in the order passed in @PMID
answered Nov 10 at 21:34
Nikhil Vartak
3,65121623
3,65121623
What if we change it toADMIN_Publication_JSON jsn INNER JOIN #Input spl on spl.PMID = jsn.PMID
? Does it works? and why we need to use a TempTable (create it and insert the data) while we can just use a window function?
– Sami
Nov 10 at 21:40
No it will not because in that case it will take up the records' order fromADMIN_Publication_JSON
table. What's the issue withLEFT JOIN
if that gives simpler query and desired output order. You can filter outnull
records from result if that worries you. What's say?
– Nikhil Vartak
Nov 10 at 21:46
I did not say my answer is better. These are just different possible ways of doing what OP needs.
– Nikhil Vartak
Nov 10 at 21:49
add a comment |
What if we change it toADMIN_Publication_JSON jsn INNER JOIN #Input spl on spl.PMID = jsn.PMID
? Does it works? and why we need to use a TempTable (create it and insert the data) while we can just use a window function?
– Sami
Nov 10 at 21:40
No it will not because in that case it will take up the records' order fromADMIN_Publication_JSON
table. What's the issue withLEFT JOIN
if that gives simpler query and desired output order. You can filter outnull
records from result if that worries you. What's say?
– Nikhil Vartak
Nov 10 at 21:46
I did not say my answer is better. These are just different possible ways of doing what OP needs.
– Nikhil Vartak
Nov 10 at 21:49
What if we change it to
ADMIN_Publication_JSON jsn INNER JOIN #Input spl on spl.PMID = jsn.PMID
? Does it works? and why we need to use a TempTable (create it and insert the data) while we can just use a window function?– Sami
Nov 10 at 21:40
What if we change it to
ADMIN_Publication_JSON jsn INNER JOIN #Input spl on spl.PMID = jsn.PMID
? Does it works? and why we need to use a TempTable (create it and insert the data) while we can just use a window function?– Sami
Nov 10 at 21:40
No it will not because in that case it will take up the records' order from
ADMIN_Publication_JSON
table. What's the issue with LEFT JOIN
if that gives simpler query and desired output order. You can filter out null
records from result if that worries you. What's say?– Nikhil Vartak
Nov 10 at 21:46
No it will not because in that case it will take up the records' order from
ADMIN_Publication_JSON
table. What's the issue with LEFT JOIN
if that gives simpler query and desired output order. You can filter out null
records from result if that worries you. What's say?– Nikhil Vartak
Nov 10 at 21:46
I did not say my answer is better. These are just different possible ways of doing what OP needs.
– Nikhil Vartak
Nov 10 at 21:49
I did not say my answer is better. These are just different possible ways of doing what OP needs.
– Nikhil Vartak
Nov 10 at 21:49
add a comment |
up vote
-1
down vote
I'm sorry to say but the currently accepted answer (by Sami) is wrong.
The problem with this answer is that it use ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
to get the order of the items in the comma delimited string, but since the order by
is done on select null
, what actually happens is that the row_number
will assign the numbers in an arbitrary order - that may or may not match the order of the strings in the source string.
If your split UDF returns a table with two columns, where one contains the substring and the other contains it's index, like Jeff Moden's DelimitedSplit8K, then simply use the ItemNumber
(or equivalent) column for the order by
. If it only returns a single column containing the substrings, you can use this a nice trick I've learned from Aaron Bertrand's Solve old problems with SQL Server’s new STRING_AGG and STRING_SPLIT functions - it will guarantee to return the correct order of the substrings as long as they are unique.
A simple change on Sami's answer will give you correct results as long as the substrings are unique within the comma delimited string - Instead of ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
, use CHARINDEX(',' + Value + ',', ',' + @Ids + ',')
, which will return the index of each substring inside the comma delimited string:
CREATE TABLE T(
ID INT,
SomeValue VARCHAR(45)
);
INSERT INTO T VALUES
(1, 'One'),
(2, 'Two'),
(3, 'Three'),
(4, 'Four'),
(5, 'Five');
DECLARE @IDs VARCHAR(200) = '3,5,2';
SELECT T.*
FROM T
INNER JOIN
(SELECT Value,
CHARINDEX(',' + Value + ',', ',' + @Ids + ',') AS Seq
FROM STRING_SPLIT(@Ids, ',') --instead of your function
) TT
ON T.ID = TT.Value
ORDER BY TT.Seq;
add a comment |
up vote
-1
down vote
I'm sorry to say but the currently accepted answer (by Sami) is wrong.
The problem with this answer is that it use ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
to get the order of the items in the comma delimited string, but since the order by
is done on select null
, what actually happens is that the row_number
will assign the numbers in an arbitrary order - that may or may not match the order of the strings in the source string.
If your split UDF returns a table with two columns, where one contains the substring and the other contains it's index, like Jeff Moden's DelimitedSplit8K, then simply use the ItemNumber
(or equivalent) column for the order by
. If it only returns a single column containing the substrings, you can use this a nice trick I've learned from Aaron Bertrand's Solve old problems with SQL Server’s new STRING_AGG and STRING_SPLIT functions - it will guarantee to return the correct order of the substrings as long as they are unique.
A simple change on Sami's answer will give you correct results as long as the substrings are unique within the comma delimited string - Instead of ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
, use CHARINDEX(',' + Value + ',', ',' + @Ids + ',')
, which will return the index of each substring inside the comma delimited string:
CREATE TABLE T(
ID INT,
SomeValue VARCHAR(45)
);
INSERT INTO T VALUES
(1, 'One'),
(2, 'Two'),
(3, 'Three'),
(4, 'Four'),
(5, 'Five');
DECLARE @IDs VARCHAR(200) = '3,5,2';
SELECT T.*
FROM T
INNER JOIN
(SELECT Value,
CHARINDEX(',' + Value + ',', ',' + @Ids + ',') AS Seq
FROM STRING_SPLIT(@Ids, ',') --instead of your function
) TT
ON T.ID = TT.Value
ORDER BY TT.Seq;
add a comment |
up vote
-1
down vote
up vote
-1
down vote
I'm sorry to say but the currently accepted answer (by Sami) is wrong.
The problem with this answer is that it use ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
to get the order of the items in the comma delimited string, but since the order by
is done on select null
, what actually happens is that the row_number
will assign the numbers in an arbitrary order - that may or may not match the order of the strings in the source string.
If your split UDF returns a table with two columns, where one contains the substring and the other contains it's index, like Jeff Moden's DelimitedSplit8K, then simply use the ItemNumber
(or equivalent) column for the order by
. If it only returns a single column containing the substrings, you can use this a nice trick I've learned from Aaron Bertrand's Solve old problems with SQL Server’s new STRING_AGG and STRING_SPLIT functions - it will guarantee to return the correct order of the substrings as long as they are unique.
A simple change on Sami's answer will give you correct results as long as the substrings are unique within the comma delimited string - Instead of ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
, use CHARINDEX(',' + Value + ',', ',' + @Ids + ',')
, which will return the index of each substring inside the comma delimited string:
CREATE TABLE T(
ID INT,
SomeValue VARCHAR(45)
);
INSERT INTO T VALUES
(1, 'One'),
(2, 'Two'),
(3, 'Three'),
(4, 'Four'),
(5, 'Five');
DECLARE @IDs VARCHAR(200) = '3,5,2';
SELECT T.*
FROM T
INNER JOIN
(SELECT Value,
CHARINDEX(',' + Value + ',', ',' + @Ids + ',') AS Seq
FROM STRING_SPLIT(@Ids, ',') --instead of your function
) TT
ON T.ID = TT.Value
ORDER BY TT.Seq;
I'm sorry to say but the currently accepted answer (by Sami) is wrong.
The problem with this answer is that it use ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
to get the order of the items in the comma delimited string, but since the order by
is done on select null
, what actually happens is that the row_number
will assign the numbers in an arbitrary order - that may or may not match the order of the strings in the source string.
If your split UDF returns a table with two columns, where one contains the substring and the other contains it's index, like Jeff Moden's DelimitedSplit8K, then simply use the ItemNumber
(or equivalent) column for the order by
. If it only returns a single column containing the substrings, you can use this a nice trick I've learned from Aaron Bertrand's Solve old problems with SQL Server’s new STRING_AGG and STRING_SPLIT functions - it will guarantee to return the correct order of the substrings as long as they are unique.
A simple change on Sami's answer will give you correct results as long as the substrings are unique within the comma delimited string - Instead of ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
, use CHARINDEX(',' + Value + ',', ',' + @Ids + ',')
, which will return the index of each substring inside the comma delimited string:
CREATE TABLE T(
ID INT,
SomeValue VARCHAR(45)
);
INSERT INTO T VALUES
(1, 'One'),
(2, 'Two'),
(3, 'Three'),
(4, 'Four'),
(5, 'Five');
DECLARE @IDs VARCHAR(200) = '3,5,2';
SELECT T.*
FROM T
INNER JOIN
(SELECT Value,
CHARINDEX(',' + Value + ',', ',' + @Ids + ',') AS Seq
FROM STRING_SPLIT(@Ids, ',') --instead of your function
) TT
ON T.ID = TT.Value
ORDER BY TT.Seq;
answered Nov 11 at 6:33
Zohar Peled
51k73171
51k73171
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53243136%2fprecise-sort-order-of-records-that-were-found-in-a-in-split-function-in-sql-serv%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Currently 2016 but I have access to 2012 also
– user1314159
Nov 10 at 20:45