2012-08-22 4 views
2

데이터를 저장하는 방식이 이전 데이터베이스에서 새 데이터베이스로 마이그레이션하려고하면 조금 다릅니다.TSQL : 한 열을 세미콜론으로 구분 된 값으로 여러 행으로 분할

특정 경우에는 여러 행으로 분리하려는 세미콜론으로 구분 된 값이있는 열이 있습니다. 이다

idperson roleperson 
1001 214401 
1002 214401 
1002 214201 
1003 212101 

가, 내가 원하는 :

SELECT 
    p.idperson, 
    p.roleperson 
FROM person p 

TSQL 위

idperson roleperson 
1001 ;214401; 
1002 ;214201;214401; 
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를 사용하면 몇 분이면 최고의 실적을 올릴 수 있습니다. –

관련 문제