Sqlserver
 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:"Масиви и списъци в 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Първи код на Entity Framework - Промяна на сортирането на колони в таблицата

  2. Изберете, модифицирайте и вмъкнете в същата таблица

  3. Най-доброто ниво на изолация за избягване на задънени блокировки с помощта на изречение UPDATE в Sql Server 2005

  4. Как да използвате use if..else в Data Flow въз основа на стойности на потребителски променливи в SSIS

  5. Как да коригирате „В списъка за избор може да бъде посочен само един израз…“ в SQL Server