J'essaye de créer une fonction de partage SQL qui fonctionne en sens inverse. Veux dire Entrée: 'Test1,Test2,Test3,Test4'

Et la sortie devrait être:

|  ID  |  Value  | 

|  1   |  Test4  | 
|  2   |  Test3  |
|  3   |  Test2  |
|  4   |  Test1  |

J'ai trouvé une fonction avancée mais je ne sais pas quoi changer pour la faire fonctionner inversée. J'ai essayé des trucs mais ça ne marche pas.

Voici l'original

CREATE FUNCTION [dbo].[SplitString]
(
 @InputString VARCHAR(8000),
 @Delimiter CHAR(1) 
)
RETURNS TABLE
AS
RETURN
(
 WITH Split(StartPos,Endpos)
 AS(
 SELECT 0 AS StartPos, CHARINDEX(@Delimiter,@InputString) AS Endpos
 UNION ALL
 SELECT Endpos+1, CHARINDEX(@Delimiter,@InputString,Endpos+1)
 FROM Split
 WHERE Endpos > 0
 )
 SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
 'Value' = SUBSTRING(@InputString,StartPos
           ,COALESCE(NULLIF(Endpos,0)
           ,LEN(@InputString)+1)-StartPos)
 FROM Split
)
GO

Avec

SELECT ID, Value 
FROM dbo.SplitString('Test1,Test2,Test3,Test4', ',');

Vous obtiendrez la sortie.

2
Christian Frei 6 avril 2017 à 18:02

2 réponses

Meilleure réponse
Select * from [dbo].[udf-Str-Parse-8K-Rev]('Test1,Test2,Test3,Test4',',')

Retours

RetSeq  RetVal
1       Test4
2       Test3
3       Test2
4       Test1

L'UDF

CREATE FUNCTION [dbo].[udf-Str-Parse-8K-Rev] (@String varchar(max),@Delimiter varchar(25))
Returns Table 
As
Return (  
    with   cte1(N)   As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
           cte2(N)   As (Select Top (IsNull(DataLength(@String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 a,cte1 b,cte1 c,cte1 d) A ),
           cte3(N)   As (Select 1 Union All Select t.N+DataLength(@Delimiter) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter)) = @Delimiter),
           cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(@Delimiter,@String,s.N),0)-S.N,8000) From cte3 S)

    Select RetSeq = Row_Number() over (Order By A.N Desc)
          ,RetVal = LTrim(RTrim(Substring(@String, A.N, A.L)))
    From   cte4 A
);
--Orginal Source http://www.sqlservercentral.com/articles/Tally+Table/72993/
--Select * from [dbo].[udf-Str-Parse-8K-Rev]('Dog,Cat,House,Car',',')

Notez l'ordre par dans la sélection finale

1
John Cappelletti 6 avril 2017 à 15:11

Vous pouvez également le faire avec une requête comme celle-ci:

SELECT
    cnt.n AS ID
    , SUBSTRING_INDEX(SUBSTRING_INDEX('Test1,Test2,Test3,Test4', ',', cnt.n),',',-1) AS `VALUE` FROM
    ( SELECT 1 AS n UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 
        UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
    ) cnt
WHERE 
    cnt.n <= CHARACTER_LENGTH('Test1,Test2,Test3,Test4') 
    - CHARACTER_LENGTH(REPLACE('Test1,Test2,Test3,Test4',',',''))+1;

échantillon

MariaDB [(none)]> SELECT
    ->     cnt.n AS ID
    ->     , SUBSTRING_INDEX(SUBSTRING_INDEX('Test1,Test2,Test3,Test4', ',', cnt.n),',',-1) AS `VALUE` FROM
    ->     ( SELECT 1 AS n UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
    ->         UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
    ->     ) cnt
    -> WHERE
    ->     cnt.n <= CHARACTER_LENGTH('Test1,Test2,Test3,Test4')
    ->     - CHARACTER_LENGTH(REPLACE('Test1,Test2,Test3,Test4',',',''))+1;
+----+-------+
| ID | VALUE |
+----+-------+
|  1 | Test1 |
|  2 | Test2 |
|  3 | Test3 |
|  4 | Test4 |
+----+-------+
4 rows in set (0.00 sec)

MariaDB [(none)]>
0
Bernd Buffen 6 avril 2017 à 15:20