sql >> Database >  >> RDS >> Sqlserver

Efficiënte manier om strings te splitsen met CTE

Je lijkt vastbesloten om een ​​CTE te gebruiken, dus probeer dit:

DECLARE @YourTable table (RowID int, Layout varchar(200))
INSERT @YourTable VALUES (1,'hello,world,welcome,to,tsql')
INSERT @YourTable VALUES (2,'welcome,to,stackoverflow')

;WITH SplitSting AS
(
    SELECT
        RowID,LEFT(Layout,CHARINDEX(',',Layout)-1) AS Part
            ,RIGHT(Layout,LEN(Layout)-CHARINDEX(',',Layout)) AS Remainder
        FROM @YourTable
        WHERE Layout IS NOT NULL AND CHARINDEX(',',Layout)>0
    UNION ALL
    SELECT
        RowID,LEFT(Remainder,CHARINDEX(',',Remainder)-1)
            ,RIGHT(Remainder,LEN(Remainder)-CHARINDEX(',',Remainder))
        FROM SplitSting
        WHERE Remainder IS NOT NULL AND CHARINDEX(',',Remainder)>0
    UNION ALL
    SELECT
        RowID,Remainder,null
        FROM SplitSting
        WHERE Remainder IS NOT NULL AND CHARINDEX(',',Remainder)=0
)
SELECT * FROM SplitSting ORDER BY RowID

UITGANG:

RowID       Part                   
----------- -----------------------
1           hello                  
1           world                  
1           welcome                
1           to                     
1           tsql                   
2           welcome                
2           to                     
2           stackoverflow          

(8 row(s) affected)

hier is een uitstekend artikel over het splitsen van strings in SQL Server:"Arrays en lijsten in SQL Server 2005 en verder, wanneer tabelwaardeparameters het niet snijden" door Erland Sommarskog

BEWERKEN hier is een andere versie (maar je hebt een getallentabel nodig) geeft dezelfde resultaten als hierboven:

;WITH SplitValues AS
(
    SELECT
        RowID,ListValue
        FROM (SELECT
                  RowID, LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(',', List2, number+1)-number - 1))) AS ListValue
                  FROM (
                           SELECT RowID, ',' + Layout + ',' AS List2
                           FROM @YourTable
                       ) AS dt
                      INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
                  WHERE SUBSTRING(List2, number, 1) = ','
             ) dt2
        WHERE ListValue IS NOT NULL AND ListValue!=''
)
SELECT * FROM SplitValues

zie hier voor een getallentabel:Wat is de beste manier om een ​​getallentabel te maken en in te vullen?



  1. Joomla:Helperfunctie aanroepen vanuit een model?

  2. Omgaan met complexe WHERE-clausules met een PHP Query Builder

  3. lange waarde opslaan in Android-database

  4. Krijg het aantal rijen dat overeenkomt met de UPDATE-query met PHP mysqli