2017-09-21 2 views
1

Considérons le problème ci-dessous: J'ai deux chaînes pour Split:fusionner deux STRING_SPLIT

STR1 = 'b;a;c;d;e' 

STR2 = '3;1;4;2;5' 

Je veux diviser et fusionner ces deux chaînes en fonction de leur indice, de sorte que le résultat est:

b -> 3 
a -> 1 
c -> 4 
d -> 2 
e -> 5 

J'ai essayé avec STRING_SPLIT, mais order by les trie tous.

SELECT A.VALUE, B.VALUE FROM (
    SELECT VALUE, ROW_NUMBER() OVER(ORDER BY VALUE) AS RW 
    FROM STRING_SPLIT('b;a;c;d;e', ';') 
) A 
INNER JOIN (
    SELECT VALUE, ROW_NUMBER() OVER(ORDER BY VALUE) AS RW 
    FROM STRING_SPLIT('3;1;4;2;5', ';') 
) B 
ON A.RW = B.RW 

Cela produit le résultat suivant:

a 1 
b 2 
c 3 
d 4 
e 5 
+0

pour référence à SQL 2016 'STRING_SPLIT': https://docs.microsoft.com/en-us/sql/t -sql/functions/string-split-transact-sql – Tanner

+1

vous pouvez utiliser 2 requêtes avec 'row_number' et les joindre, ne pas avoir 2016 donc ne peut pas tester, même si vous mai besoin de commander les résultats de sorte que ne peut pas fonctionner – Tanner

+0

vous voulez physiquement cette flèche? – scsimon

Répondre

4

Jeff Peut-être quelque chose comme ça?

declare @STR1 varchar(64) = 'b;a;c;d;e' 

declare @STR2 varchar(64) = '3;1;4;2;5' 

;with cte as(
select 
    value 
    ,RN = row_number() over (order by (select null)) 
from 
    STRING_SPLIT(@STR1,';')), 

cte2 as(
select 
    value 
    ,RN = row_number() over (order by (select null)) 
from 
    STRING_SPLIT(@STR2,';')) 

select 
    c.value + d.value 
from 
    cte c 
    inner join 
    cte2 d on c.RN = d.RN 
+0

Cela a fonctionné absolument bien. Merci beaucoup. J'essayais 'Order by null'. – Nabid

+0

Savons-nous si STRING_SPLIT renvoie toujours les résultats dans l'ordre des valeurs fournies? Si ce n'est pas le cas, cela pourrait bien fonctionner jusqu'à ce que la liste de chaînes soit plus longue et que cela puisse commencer à s'écailler. –

+0

J'ai cherché intensivement sur ce @SeanLange précédemment et n'a pu trouver aucun essai dur là-dessus. Comme vous, je pense qu'il y aurait un moyen pour que cela devienne irrecevable, mais il n'y a rien là-dessus. Cependant, je n'ai pas vu une fonction de split construite par l'utilisateur qui renvoie une table dans un ordre arbitraire, donc je ne m'attendrais pas à ce que Microsoft le fasse. Je m'attendrais à ce qu'ils le gardent explicite. Les docs indiquent le retour d'un exemple sans parler explicitement de l'ordre. * SELECT valeur de STRING_SPLIT ('Lorem ipsum dolor sit amet.', '') * Indique qu'il reviendrait (et le donner dans l'ordre) – scsimon

2

STRING_SPLIT ne renvoie pas de numéro de ligne. Cela ne fonctionnerait pas pour vos besoins.

J'utilise ici DelimitedSplit8K http://www.sqlservercentral.com/articles/Tally+Table/72993/

declare @STR1 varchar(20) = 'b;a;c;d;e' 

declare @STR2 varchar(20) = '3;1;4;2;5' 

select s1.Item , s2.Item 
from DelimitedSplit8K (@STR1, ';') s1 
    inner join DelimitedSplit8K (@STR2, ';') s2 on s1.ItemNumber = s2.ItemNumber 
order by s1.ItemNumber 
0

Une autre façon de le faire sans dépendre de la fonction STRING_SPLIT():

DECLARE @xml  AS XML, 
     @xml2  AS XML, 
     @str  AS VARCHAR(100), 
     @str2  AS VARCHAR(100), 
     @delimiter AS VARCHAR(10) 

SET @str='b;a;c;d;e' 
SET @str2 = '3;1;4;2;5' 
SET @delimiter =';' 
SET @xml = Cast(('<X>' + Replace(@str, @delimiter, '</X><X>') 
        + '</X>') AS XML) 
SET @xml2 = Cast(('<X>' + Replace(@str2, @delimiter, '</X><X>') 
        + '</X>') AS XML) 

SELECT a.value, 
     b.value 
FROM (SELECT n.value('.', 'varchar(10)') AS value, 
       Row_number() 
       OVER ( 
        ORDER BY (SELECT 100)) AS SNO 
     FROM @xml.nodes('X') AS T(n))a 
     INNER JOIN (SELECT n.value('.', 'varchar(10)') AS value, 
          Row_number() 
          OVER ( 
           ORDER BY (SELECT 100)) AS SNO 
        FROM @xml2.nodes('X') AS T(n))b 
       ON a.sno = b.sno