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










share|improve this question
























  • Currently 2016 but I have access to 2012 also
    – user1314159
    Nov 10 at 20:45















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










share|improve this question
























  • Currently 2016 but I have access to 2012 also
    – user1314159
    Nov 10 at 20:45













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










share|improve this question















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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


















  • 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












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






share|improve this answer























  • 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 need ROW_NUMBER()
    – Nikhil Vartak
    Nov 10 at 21:30


















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 Splits 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






share|improve this answer





















  • 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










  • 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


















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;





share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    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

























    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






    share|improve this answer























    • 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 need ROW_NUMBER()
      – Nikhil Vartak
      Nov 10 at 21:30















    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






    share|improve this answer























    • 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 need ROW_NUMBER()
      – Nikhil Vartak
      Nov 10 at 21:30













    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






    share|improve this answer














    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







    share|improve this answer














    share|improve this answer



    share|improve this answer








    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 need ROW_NUMBER()
      – Nikhil Vartak
      Nov 10 at 21:30


















    • 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 need ROW_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












    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 Splits 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






    share|improve this answer





















    • 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










    • 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















    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 Splits 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






    share|improve this answer





















    • 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










    • 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













    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 Splits 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






    share|improve this answer












    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 Splits 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







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 10 at 21:34









    Nikhil Vartak

    3,65121623




    3,65121623












    • 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










    • 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












    • 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
















    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










    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;





    share|improve this answer

























      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;





      share|improve this answer























        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;





        share|improve this answer












        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;






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 11 at 6:33









        Zohar Peled

        51k73171




        51k73171






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Full-time equivalent

            Bicuculline

            さくらももこ