SQL XML Problemas explícitos con la creación de árbol XML (padre-hijo)
-
21-12-2019 - |
Pregunta
Estoy enfrentando algunos problemas con XML explícito en SQL Server, donde no emite XML de acuerdo con la relación que especifiqué en SQL Query.La consulta se realiza en la base de datos de pubs y, aunque la ruta XML es más fácil de usar, la necesidad de mi entrenador, se realiza en XML explícita.
SELECT 1 AS Tag,
NULL AS Parent,
NULL AS [TitleTypes!1],
NULL AS [TitleType!2!Type],
NULL AS [TitleType!2!AveragePrice],
NULL AS [Title!3!title_id],
NULL AS [Title!3!price]
UNION ALL
SELECT 2,
1,
NULL ,
type AS [TitleType!2!Type],
AVG(price) AS [TitleType!2!AveragePrice],
NULL AS [Title!3!title_id],
NULL AS [Title!3!price]
from titles
GROUP BY type
UNION ALL
SELECT 3,
2,
NULL ,
type AS [TitleType!2!Type],
NULL AS [TitleType!2!AveragePrice],
title_id AS [Title!3!title_id],
price AS [Title!3!price]
from titles
FOR XML EXPLICIT;
La salida que produce:
<TitleTypes>
<TitleType Type="business " AveragePrice="13.7300" />
<TitleType Type="mod_cook " AveragePrice="11.4900" />
<TitleType Type="popular_comp" AveragePrice="21.4750" />
<TitleType Type="psychology " AveragePrice="13.5040" />
<TitleType Type="trad_cook " AveragePrice="15.9633" />
<TitleType Type="UNDECIDED ">
<Title title_id="BU1032" price="19.9900" />
<Title title_id="BU1111" price="11.9500" />
<Title title_id="BU2075" price="2.9900" />
<Title title_id="BU7832" price="19.9900" />
<Title title_id="MC2222" price="19.9900" />
<Title title_id="MC3021" price="2.9900" />
<Title title_id="MC3026" />
<Title title_id="PC1035" price="22.9500" />
<Title title_id="PC8888" price="20.0000" />
<Title title_id="PC9999" />
<Title title_id="PS1372" price="21.5900" />
<Title title_id="PS2091" price="10.9500" />
<Title title_id="PS2106" price="7.0000" />
<Title title_id="PS3333" price="19.9900" />
<Title title_id="PS7777" price="7.9900" />
<Title title_id="TC3218" price="20.9500" />
<Title title_id="TC4203" price="11.9500" />
<Title title_id="TC7777" price="14.9900" />
</TitleType>
</TitleTypes>
La salida que quiero:
<TitleTypes>
<TitleType Type="business" AveragePrice="11.22">
<Title title_id="BU1111" Price="11.34"/>
<Title title_id="TC7777" Price="14.2"/>
</TitleType>
<TitleType Type="popular_comp" AveragePrice="13.99">
<Title title_id="BU1111" Price="15.9"/>
<Title title_id="TC7777" Price="16.22"/>
</TitleType>
</TitleTypes>
Solución
Por lo general, no necesita un modo explícito en absoluto.Puedes generar casi todos los XML. Quiero con para la ruta XML :
select
t1.type as [@Type],
avg(t1.price) as [@AveragePrice],
(
select
t2.title_id as [@title_id],
t2.price as [@price]
from titles as t2
where t2.type = t1.type
for xml path('Title'), type
)
from titles as t1
group by t1.type
for xml path('TitleType'), root('TitleTypes')
Pero dado que su XML es un atributo centrado, es aún más fácil para usted usar >>para XML RAW :
select
t1.type as [Type],
avg(t1.price) as AveragePrice,
(
select
t2.title_id
t2.price
from titles as t2
where t2.type = t1.type
for xml raw('Title'), type
)
from titles as t1
group by t1.type
for xml raw('TitleType')
Otros consejos
Aquí está la solución que funcionó para mí.Mira en el orden por la cláusula.Si está utilizando SQL Server Management Studio en orden por cláusula, le mostrará un posible nombre de columna por el cual puede formatear su salida XML como desee.
SELECT 1 AS Tag,
NULL AS Parent,
NULL AS [TitleTypes!1],
NULL AS [TitleType!2!Type],
NULL AS [TitleType!2!AveragePrice],
NULL AS [Title!3!title_id],
NULL AS [Title!3!price]
UNION ALL
SELECT 2,
1,
NULL ,
type AS [TitleType!2!Type],
AVG(price) AS [TitleType!2!AveragePrice],
NULL AS [Title!3!title_id],
NULL AS [Title!3!price]
from titles
GROUP BY type
UNION ALL
SELECT 3,
2,
NULL ,
type AS [TitleType!2!Type],
NULL AS [TitleType!2!AveragePrice],
title_id AS [Title!3!title_id],
price AS [Title!3!price]
from titles
ORDER BY [TitleTypes!1], [TitleType!2!Type], [Title!3!title_id] ,Tag
FOR XML EXPLICIT;
P.s.Para XML explícito succiona.Pero si está desarrollando / actualizando un sistema realmente antiguo, debe conocerlo antes de reemplazar con técnicas más nuevas.