Разбейте несколько элементов XML на несколько столбцов - PullRequest
0 голосов
/ 31 мая 2019

Я пытаюсь разбить этот столбец xml на несколько столбцов xml, но, похоже, он имеет неправильный формат.

Вот мои данные об использовании xml path ()

<claim id="1111111">
  <InsHistDB>2</InsHistDB>
  <ClaimHistID>111111</ClaimHistID>
  <PatID>00000001</PatID>
  <ProcedureData>
    <row proc_logid="0000009" proc_logdb="1000000" createdate="2000-09-21T00:00:00" pldate="2000-09-21T00:00:00" adacode="D0120" />
    <row proc_logid="1211557" proc_logdb="1000010" createdate="2015-09-21T00:00:00" pldate="2015-09-21T00:00:00" adacode="D0220" />
    <row proc_logid="1211558" proc_logdb="1000010" createdate="2015-09-21T00:00:00" pldate="2015-09-21T00:00:00" adacode="D0230" />
    <row proc_logid="1211556" proc_logdb="1000010" createdate="2015-09-21T00:00:00" pldate="2015-09-21T00:00:00" adacode="D0272" />
  </ProcedureData>
</claim>

В настоящий момент оператором выбора является

SELECT TOP (1000)  [ClaimID] as '@id'
      ,[InsHistDB]
      ,[ClaimHistID]
      ,[PatID]
   -- ,[ProcedureData].value('declare namespace ns= "ProcedureData"; (/ns:ProcedureData/ns:row[1])','nvarchar(50)') as pp
     ,[ProcedureData]
     --,[ProcedureData].query('proc_logid').value('.','varchar(50)') as 'proc_1'
  FROM [Mine].[dbo].[claim]
  where claimid=1111111

 FOR XML PATH('claim')

Что я хочу сделать, это разделить{Proc_Log_id} в разные столбцы, поэтому строка должна читаться.

Claim ID         INSHISTDB       CLaimHistID       PATID      Proc_Id1      Proc_ID2      ProcID3   procID4
 11111              2               1111111      000000001     0000009    1211557        1211558      1211556                   

Возможно ли это, или я просто вращаю свои колеса?Также это будет для нескольких пати, так что ожидается запрос без предложения where.Также я считаю, что может быть до 10 proc_logids на одну точку данных xml.Я в порядке с нулевыми значениями, так как я планирую повернуть и нормализовать эти данные.

Спасибо за чтение.

Ответы [ 2 ]

0 голосов
/ 31 мая 2019

Вы можете сначала построить график идентификаторов из вашего XML-контента, а затем вам нужно использовать PIVOT, как вы упомянули. Поскольку вы не уверены в количестве столбцов, вы можете использовать динамический свод, чтобы сделать его более гибким.

Сначала получите данные, используя узлы и значения XML, и я сохранил значение во временной таблице, так как было бы удобно сделать сводную таблицу.

Declare @xmlstring xml =  
'<claim id="1111111">
  <InsHistDB>2</InsHistDB>
  <ClaimHistID>111111</ClaimHistID>
  <PatID>00000001</PatID>
  <ProcedureData>
    <row proc_logid="0000009" proc_logdb="1000000" createdate="2000-09-21T00:00:00" pldate="2000-09-21T00:00:00" adacode="D0120" />
    <row proc_logid="1211557" proc_logdb="1000010" createdate="2015-09-21T00:00:00" pldate="2015-09-21T00:00:00" adacode="D0220" />
    <row proc_logid="1211558" proc_logdb="1000010" createdate="2015-09-21T00:00:00" pldate="2015-09-21T00:00:00" adacode="D0230" />
    <row proc_logid="1211556" proc_logdb="1000010" createdate="2015-09-21T00:00:00" pldate="2015-09-21T00:00:00" adacode="D0272" />
  </ProcedureData>
</claim>' 

if object_id('tempdb..#temp1') is not null 
drop table #temp1

select m.Col.value('@id','varchar(150)') as ClaimID
,m.Col.value('(InsHistDB)[1]','varchar(150)') as InsHistDB 
,m.Col.value('(ClaimHistID)[1]','varchar(150)') as ClaimHistID 
,m.Col.value('(PatID)[1]','varchar(150)') as PatID
,t.new.value('(@proc_logid)[1]', 'Varchar(150)') IDcol, 
concat('Proc_ID', cast(ROW_NUMBER() over (Partition by m.Col.value('@id','varchar(150)') order by t.new.value('(@proc_logid)[1]', 'Varchar(150)')) as varchar(10))) AS ProcID 
into #temp1   
from @xmlstring.nodes('/claim') as m(col)
CROSS APPLY @xmlstring.nodes('claim/ProcedureData/row') as t(new);

У вас будут данные во временной таблице, подобные этой. Я объединил rownumber для данного requestID с идентификатором proc, чтобы создать столбец, как вы упомянули.

ClaimID    InsHistDB    ClaimHistID PatID   IDcol   ProcID
1111111       2          111111    00000001 0000009 Proc_ID1
1111111       2          111111    00000001 1211557 Proc_ID2
1111111       2          111111    00000001 1211558 Proc_ID3
1111111       2          111111    00000001 1211556 Proc_ID4

Затем вы можете использовать динамический разворот, чтобы получить ожидаемый результат.

DECLARE @cols AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX);

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.procID) 
        FROM #temp1 c
        FOR XML PATH(''))  
    ,1,1,'')


    set @query = 'SELECT ClaimID, InsHistDB,ClaimHistID, PatID,  '+@cols+'  from 
        (
            select ClaimID, InsHistDB,ClaimHistID, PatID, procID, IDcol  

                from #temp1
       ) x
        pivot 
        (
             max(IDcol)
            for procID in (' + @cols + ')
        ) p '

Exec sp_executesql @query

Окончательный результат запроса:

ClaimID InsHistDB   ClaimHistID PatID   Proc_ID1    Proc_ID2    Proc_ID3    Proc_ID4
1111111     2        111111    00000001 0000009     1211557     1211558     1211556
0 голосов
/ 31 мая 2019

Синтаксис для выбора третьего узла: column.value('(/foo/bar)[3]','varchar(25)').

Вы вправе рассмотреть другие варианты. В частности, функции «запрос» или «узлы» лучше подходят, поскольку они могут возвращать значения в качестве второго результирующего набора или нового XML-документа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...