sql >> データベース >  >> RDS >> Sqlserver

CTE を使用した文字列分割の効率的な方法

    あなたは CTE の使用に夢中になっているようです。これを試してください:

    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
    

    出力:

    RowID       Part                   
    ----------- -----------------------
    1           hello                  
    1           world                  
    1           welcome                
    1           to                     
    1           tsql                   
    2           welcome                
    2           to                     
    2           stackoverflow          
    
    (8 row(s) affected)
    

    SQL Server での文字列の分割に関する優れた記事:"Arrays and Lists in SQL Server 2005 以降、テーブル値のパラメーターがうまくいかない場合" Erland Sommarskog 著

    編集 これは別のバージョンです (ただし、数字の表が必要です) は、上記と同じ結果を返します:

    ;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
    

    数値表については、こちらを参照してください:数値表を作成して入力する最良の方法は何ですか?



    1. mysqlcppconn.libをc++プロジェクトにリンクする方法

    2. Postgres関数は作成されますが、実行されません

    3. Oracle行の複数の列でピボットを使用する

    4. PHPでfalseを返すSQLクエリ