2017-11-30 8 views
0

장시간 lurker, 처음 질문 묻는 사람 ...다중 값, 문자 구분 열을 여러 행으로 분할하는 방법은 무엇입니까?

친숙한 것 같지만이 특정 문제에 대한 답을 찾지 못했습니다.

세미콜론으로 구분 된 값 목록을 포함하는 열이있는 테이블이 있습니다. 테이블은 해당 응용 프로그램과 연관된 서버와 함께 응용 프로그램의 목록입니다. 서버 목록은 세미콜론으로 구분되지만 serverId로 구분됩니다. x 서버 수에 대한 serverName - 몇 가지 응용 프로그램이 수백 개의 서버와 연관되어 있으며 일부는 1과 연관되어 있으며 일부는 0과 연관되어 있습니다. 이 서버 열은 테이블의 ID와 열의 serverId 및 serverName을 포함하여 각 고유 서버에 대한 행으로 구성됩니다.

이 데이터는 현재이 같은이

applicationId\Servers 1\serverId1;serverName1 2\serverId2;serverName2;serverId3;serverName3 3\serverId1;serverName1;serverId5;serverName5;serverId8;serverName8 4\serverId9;serverName9 5\

나는 작은 애플리케이션, 서버 ID와 새 테이블을 만들고 싶습니다

및 서버 이름 컬럼과 같다 : 또는

applicationId\serverId\serverName 1\serverId1\serverName1 2\serverId2\serverName2 2\serverId3\serverName3 3\serverId1\serverName1 3\serverId5\serverName5 3\serverId8\serverName8 4\serverId9\serverName9 5\

, 만약 내가 serverId와 serverName,뿐만 아니라 테이블을 가지고 도움이 될 것입니다 applicationId와 테이블에 serverId를 얻을 수 있습니다.

applicationId\serverId

난 그냥에 열을 분할 시도 ';' 하지만 다음과 같이하지 매우 도움이 출력을 생성합니다

applicationId\serverColumn 1\serverId1 1\serverName1 2\serverId2 2\serverName2 2\serverId3 2\serverName3 ....

어떤 도움을 크게 감상 할 수있다.

+1

여기서 가장 큰 문제는이 구분 된 데이터를 저장하는 것입니다. 이제 구분 된 버전을 다른 버전으로 옮기고 싶습니다. 이것은 좋은 계획이 아닙니다. 대신 이것을 정규화 된 디자인으로 이동하는 것을 고려해야합니다. –

+0

문제는 하나의 테이블에 '일대 다 (one to many)'관계를 저장했다는 것입니다. 이 문제뿐만 아니라 데이터를 정규화하여 해결하십시오. 그러나 이것에 대한 앞으로의 모든 문제는 사라질 것입니다. – GuidoG

+0

불행히도이 방법을 사용하면 데이터를 소비 할 수있는 유일한 방법입니다. 그렇지 않으면 확실히 이런 식으로 디자인하지 않을 것입니다. – MattAtWork

답변

2

이것은 최소한의 것을 말하기위한 엄청난 데이터 구조입니다. 그러나 Jeff Moden의 스플리터를 사용하는 것이 가능합니다. http://www.sqlservercentral.com/articles/Tally+Table/72993/ 당신은 스플리터가 있다고 말하지만, 루프 나 반복적 인 cte가 있다면 Jeff 's와 같은 세트 기반의 것을 위해 버려야합니다.

다음은이 스플리터를 사용하여 어떻게 작동하는지 보여주는 완전한 예입니다.

declare @Something table 
(
    ApplicationID int 
    , ServerInfo varchar(100)) 
insert @Something 
(
    ApplicationID 
    , ServerInfo 
) values 
(1, 'serverId1;serverName1') 
, (2, 'serverId2;serverName2;serverId3;serverName3') 
, (3, 'serverId1;serverName1;serverId5;serverName5;serverId8;serverName8') 
, (4, 'serverId9;serverName9') 
; 

with ServerIDs as 
(
    select s.ApplicationID 
     , ServerID = case when x.ItemNumber % 2 = 1 then x.Item end 
     , x.ItemNumber 
    from @Something s 
    cross apply dbo.DelimitedSplit8K(s.ServerInfo, ';') x 
    where x.ItemNumber % 2 = 1 
) 
, ServerNames as 
(
    select s.ApplicationID 
     , ServerName = case when x.ItemNumber % 2 = 0 then x.Item end 
     , x.ItemNumber 
    from @Something s 
    cross apply dbo.DelimitedSplit8K(s.ServerInfo, ';') x 
    where x.ItemNumber % 2 = 0 
) 

select si.ApplicationID 
    , si.ServerID 
    , sn.ServerName 
from ServerIDs si 
join ServerNames sn on sn.ApplicationID = si.ApplicationID and si.ItemNumber + 1 = sn.ItemNumber 

이 반환

ApplicationID ServerID ServerName 
1    serverId1 serverName1 
2    serverId2 serverName2 
2    serverId3 serverName3 
3    serverId1 serverName1 
3    serverId5 serverName5 
3    serverId8 serverName8 
4    serverId9 serverName9 
+0

이것은 트릭을했다! 고맙습니다! 나는이 작업을하기 위해 모듈러스 연산을 사용하는 것을 생각하지 않았지만 총체적인 이해와 훌륭한 작업을합니다. – MattAtWork

+1

도움이 된 것을 기쁘게합니다. 그러나 심각하게는 ... 구분 된 데이터를 저장하는 것보다 나은 접근법을 찾으십시오. –