2017-06-30 19 views
9

Mam wymagania, jak poniżej.Konwersja wierszy do formatu XML w SQL Server

enter image description here

I DDL i DML skrypt na powyższym zdjęciu jest

CREATE TABLE #example 
    ([CCP_DETAILS_SID] int, [ACCOUNT_GROWTH] int, [PRODUCT_GROWTH] int, [PROJECTION_SALES] numeric(22,6), [PROJECTION_UNITS] numeric(22,6), [PERIOD_SID] int) 
; 

INSERT INTO #example 
    ([CCP_DETAILS_SID], [ACCOUNT_GROWTH], [PRODUCT_GROWTH], [PROJECTION_SALES], [PROJECTION_UNITS], [PERIOD_SID]) 
VALUES 
    (30001, 0, 0, 1505384.695, 18487.25251, 1801), 
    (30001, 0, 0, 1552809.983, 18695.75536, 1802), 
    (30001, 0, 0, 1595642.121, 18834.75725, 1803), 
    (30002, 0, 0, 10000.32, 18834.75725, 1801), 
    (30002, 0, 0, 1659124.98, 18834.75725, 1802), 
    (30002, 0, 0, 465859546.6, 18834.75725, 1803) 
; 

i muszę konwertować powyższe wyniki w formacie xml jak poniżej (wyjścia).

ccp_details_sid   xml_format_string 

30001      <period> 
          <period_sid period_sid=1801> 
          <PROJECTION_SALES>1505384.695</PROJECTION_SALES> 
          <PROJECTION_UNITS>18487.25251<PROJECTION_UNITS> 
          <ACCOUNT_GROWTH>0</ACCOUNT_GROWTH> 
          <PRODUCT_GROWTH>0</PRODUCT_GROWTH> 
          </period_sid> 
          <period_sid period_sid=1802> 
          <PROJECTION_SALES>1552809.983</PROJECTION_SALES> 
          <PROJECTION_UNITS>18695.75536<PROJECTION_UNITS> 
          <ACCOUNT_GROWTH>0</ACCOUNT_GROWTH> 
          <PRODUCT_GROWTH>0</PRODUCT_GROWTH> 
          </period_sid> 
          <period_sid period_sid=1802> 
          <PROJECTION_SALES>1595642.121</PROJECTION_SALES> 
          <PROJECTION_UNITS>18834.75725<PROJECTION_UNITS> 
          <ACCOUNT_GROWTH>0</ACCOUNT_GROWTH> 
          <PRODUCT_GROWTH>0</PRODUCT_GROWTH> 
          </period_sid> 
          </period> 

30002      Same like above  

Jestem nowy XML więc nie mogłem w stanie zrobić to szybko. Użyłem rozwiązania Marc_s z cross apply, ale nie jestem w stanie go osiągnąć.

Uwaga: moim głównym celem jest, na powyższym obrazku, jeśli widzimy, że istnieją trzy rekordy dla pojedynczego ccp_details_sid, więc chcę go przekonwertować jako jeden wiersz przy użyciu XML (wspomnianego powyżej).

+5

Dobre pytanie! Doceniam skrypt * copy'n'pasteable *! +1 z mojej strony – Shnugo

Odpowiedz

13

Poniższa będzie pracować dla Ciebie:

SELECT t.CCP_DETAILS_SID, 
     ( SELECT PERIOD_SID AS [@period_sid], 
        x.PROJECTION_SALES, 
        x.PROJECTION_UNITS, 
        x.ACCOUNT_GROWTH, 
        x.PRODUCT_GROWTH 
      FROM #Example AS x 
      WHERE x.CCP_DETAILS_SID = t.CCP_DETAILS_SID 
      FOR XML PATH('period_sid'), TYPE, ROOT('period') 
     ) AS xml_format_string 
FROM #Example AS t 
GROUP BY t.CCP_DETAILS_SID; 

Zasadniczo dostaje wszystkie swoje unikatowe wartości dla CCP_DETAILS_SID używając:

SELECT t.CCP_DETAILS_SID 
FROM #Example AS t 
GROUP BY t.CCP_DETAILS_SID; 

Następnie dla każdej z tych wartości wykorzystuje podzapytanie skorelowane tworząc XML . Kluczowymi punktami są:

  • Użyj przed numerem aliasu @, aby utworzyć właściwość, np. AS [@period_sid]
  • Zastosowanie PATH('period_sid') wymienić pojemnik na każdym rzędzie
  • użytkowania ROOT('period') wymienić zewnętrzne węzły.

Example on DBFiddle

4

użyłbym następujące podejście:

SELECT * 
FROM (SELECT DISTINCT x.[CCP_DETAILS_SID] FROM #example x) y 
OUTER APPLY (
    SELECT (
     SELECT z.[PERIOD_SID]   AS '@period_sid', 
       z.[PROJECTION_SALES] AS 'PROJECTION_SALES', 
       z.[PROJECTION_UNITS] AS 'PROJECTION_UNITS', 
       z.[ACCOUNT_GROWTH]  AS 'ACCOUNT_GROWTH', 
       z.[PRODUCT_GROWTH]  AS 'PRODUCT_GROWTH' 
     FROM #example z 
     WHERE y.[CCP_DETAILS_SID] = z.[CCP_DETAILS_SID] 
     FOR XML PATH('period_sid'), ROOT('period'), TYPE 
    ) AS XmlResults 
) z 

Demo