2016-08-24 3 views
1

SQL Server 2012 사용. 그룹 식별자와 작은 XML 조각이 포함 된 테이블이 있습니다.그룹 XML 열 데이터

<Parent> 
    <Group GroupId="1"> 
     <Item> 
      <Criteria Type="State" Values="CA"/> 
      <Criteria Type="State" Values="TX"/> 
      <Criteria Type="State" Values="FL"/> 
     </Item> 
     <Item> 
      <Criteria Type="Manager" Values="Tim"/> 
     </Item> 
    </Group> 
    <Group GroupId="2"> 
     <Item> 
      <Criteria Type="Name" Values="Walters"/> 
     </Item> 
     <Item> 
      <Criteria Type="Manager" Values="Tim"/> 
     </Item> 
    </Group> 
</Parent> 

I :

CREATE TABLE temp (
    GroupId [int] NOT NULL, 
    RawXml [xml] NULL 
) 

INSERT INTO temp VALUES (1, '<Item><Criteria Type="State" Values="CA"/><Criteria Type="State" Values="TX"/><Criteria Type="State" Values="FL"/></Item>') 
INSERT INTO temp VALUES (1, '<Item><Criteria Type="Manager" Values="Tim"/></Item>') 
INSERT INTO temp VALUES (2, '<Item><Criteria Type="Name" Values="Walters"/></Item>') 
INSERT INTO temp VALUES (2, '<Item><Criteria Type="Manager" Values="Tim"/></Item>') 

내가하고 싶은 것은 그룹이 최종 결과는 다음과 같이 구성되어 있으므로 함께 그룹 ID에 의한 XML의 조각은 더 큰 XML 문서를 형성하는 것입니다 : 다음은 샘플입니다 두 번째 유형의 string concatenation method을 사용하여 XML 열의 내용을 연결 한 다음 FOR XML select 문을 사용하는 것이 유일한 해결책이지만 두 번째 방법은 응용 프로그램에 너무 느리다는 두려움이 있습니다. 내가 누락 된 뭔가가 있고이 방법으로 XML 데이터를 그룹화하는 쉬운 방법이 있습니다 또는 문자열 연결 내 유일한 선택입니다.

+0

왜 XML을 분할하면 전체 XML을 하나의 행에 넣을 수 있습니까? 파싱하기 쉽습니다 –

+0

당신은 합창단에게 설교하고 있습니다. 솔직히, 나는 레거시 애플리케이션 코드/데이터에 묶여 있으며, 이것들은 내가 다루어 진 카드이다. 데이터가 이미 저장되는 방법을 변환하는 것도 옵션이지만, 지금은 피하려고합니다. – Stigz

+0

좋은 질문입니다! 특히 테스트 코드, copy'n'pasteable 및 예상 출력 정말 도움이됩니다! +1 – Shnugo

답변

2

는 물론 간단한 방법이있다 :. 음, 나중에 같은 테이블의 데이터베이스를 정리 싫어하기 때문에

declare @t table (
    GroupId [int] NOT NULL, 
    RawXml [xml] NULL 
); 

INSERT INTO @t 
VALUES (1, '<Item><Criteria Type="State" Values="CA"/><Criteria Type="State" Values="TX"/><Criteria Type="State" Values="FL"/></Item>'), 
(1, '<Item><Criteria Type="Manager" Values="Tim"/></Item>'), 
(2, '<Item><Criteria Type="Name" Values="Walters"/></Item>'), 
(2, '<Item><Criteria Type="Manager" Values="Tim"/></Item>'); 

select sq.GroupId as [@GroupId], 
    (
     select t.RawXml as [node()] 
     from @t t 
     where t.GroupId = sq.GroupId 
     for xml path(''), type 
    ) 
from (select distinct g.GroupId from @t g) sq 
for xml path('Group'), type, root('Parent'); 

(나는 동등한 TV와 원래의 테이블을 교체 한 그것은 아무튼 질문과 관련하여 차이점을 소개하지 마십시오.)

+0

좋은 대답, +1, 단지 하나의 작은 힌트 : 확실하지는 않지만'AS [*]'또는'AS [node()]'를''보다 낫게 사용하는 것이 조금 더 낫다고 생각합니다. 추가 둥지 레벨을 피하기 위해 query()'를 사용합니다. – Shnugo

+0

@ Shnugo, 정확히이 특정 출력을 지정하는 방법을 잊어 버렸습니다. 실제로, 실행 계획에 따르면 그 차이는 엄청납니다. 수정, 제안 주셔서 감사합니다. –

+0

대단하군요. 고맙습니다. 예,'t.RawXml은 [node()]'처럼 훨씬 빠릅니다. – Stigz