sql >> Databasteknik >  >> RDS >> Sqlserver

Det bästa sättet att extrahera data från xml med xquery

Jag har hittat en lite smutsig lösning:

select ISNULL(Age1, case when Num>= 1 then 18 else -1 end) Age1
    , ISNULL(Age2, case when Num>= 2 then 18 else -1 end) Age2
    , ISNULL(Age3, case when Num>= 3 then 18 else -1 end) Age3
    , ISNULL(Age4, case when Num>= 4 then 18 else -1 end) Age4
from (
    select Persons.Person.value('@num','smallint') as Num
          ,Persons.Person.value('xs:integer(fn:number(@num))+1','int') as Num1
          ,Persons.Person.value('Person[@age<18][xs:integer(fn:number(../@num))][1]/@age','smallint') as Age1
          ,Persons.Person.value('Person[@age<18][xs:integer(fn:number(../@num))-1][1]/@age','smallint') as Age2
          ,Persons.Person.value('Person[@age<18][xs:integer(fn:number(../@num))-2][1]/@age','smallint') as Age3
          ,Persons.Person.value('Person[@age<18][xs:integer(fn:number(../@num))-3][1]/@age','smallint') as Age4 
    from @XmlData.nodes('/Persons') Persons(Person)
 ) Persons

Tanken med en lösning är att först extrahera de kontakter som är>=18, sedan extrahera de som är 0 <ålder <18 och slutligen ställa in de som inte tillhandahålls till -1

UPD:trots att lösningen gav korrekta resultat är kostnaden hög:~1000 i beräknad utförandeplan



  1. Vad är datetime2?

  2. Hur man skapar grupper med jämn storlek

  3. Kan jag använda en SQL Server CTE för att sammanfoga korsande datum?

  4. SQL Server 2000:Idéer för att utföra sammanlänkningsunderfrågan