2012-08-22 189 views
2

嘗試從舊數據庫遷移到存儲數據方式的新數據庫有點不同。TSQL:將一列以分號分隔的值拆分爲多行

在一個特定情況下,我有一列用分號隔開的值,我想將它們分成多行。

下面是一個例子:

SELECT 
    p.idperson, 
    p.roleperson 
FROM person p 

的TSQL以上產生如下的輸出

idperson roleperson 
1001 ;214401; 
1002 ;214201;214401; 
1003 ;212101; 

我想將此轉換爲:

idperson roleperson 
1001 214401 
1002 214401 
1002 214201 
1003 212101 

即,我想將具有多個值的行分成兩行。這可能沒有創建遊標或循環?

回答

6

在寫這篇文章時,我想出了一個使用交叉應用和自定義拆分功能的簡單方法。因此,而不是隻是問的問題我會後我如何解決它使用這種自包含SQL太;)

-- set up a split function 
GO 
CREATE FUNCTION [dbo].[TempSplit] (@sep char(1), @s varchar(512)) 
RETURNS table 
AS 
RETURN (
    WITH Pieces(pn, start, stop) AS (
     SELECT 1, 1, CHARINDEX(@sep, @s) 
     UNION ALL 
     SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1) 
     FROM Pieces 
     WHERE stop > 0 
    ) 
    SELECT pn, 
     SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s 
    FROM Pieces 
) 
GO 

-- set up some test data 
DECLARE @personroles TABLE 
    (
     idperson INT, 
     rawroleoptions NVARCHAR(MAX) 
    ) 

INSERT INTO @personroles VALUES (1, ';1;2;3;') 
INSERT INTO @personroles VALUES (2, ';4;5;6;') 
INSERT INTO @personroles VALUES (3, ';7;') 

-- the actual work -- 
;WITH data AS 
(
    SELECT 
     p.idperson, 
     p.rawroleoptions 

    FROM @personroles p 
) 
SELECT * FROM data r 
CROSS APPLY 
    (SELECT s AS [ExtractedValue] FROM dbo.TempSplit(';',r.rawroleoptions) WHERE LEN(s)>0) d 

-- clean up -- 
GO 
DROP FUNCTION dbo.TempSplit 
GO 

運行以上後,這是SQL輸出。

Values split into new rows

+0

非常感謝您爲您添加解決方案!我遇到過其他方法,但使用Cross Apply是以英里計算的最佳表演者。 –