Usuário com melhor resposta
DISTINCT e XML

Pergunta
-
Respostas
-
Boa Noite,
Existem duas formas de se fazer isso. Você pode optar por uma extração e aplicar um DISTINCT posteriormente ou utilizar a própria XQUERY para fazer esse filtro. Baseando-me no seu exemplo, seguem duas possíveis soluções:
Solução 1
declare @dados xml
set @dados = '
<reservas>
<reserva id="15232" data="2007-12-27" cliente="501" local="36"/>
<reserva id="15234" data="2007-12-27" cliente="609" local="49"/>
<reserva id="15237" data="2007-12-27" cliente="129" local="36"/>
<reserva id="15238" data="2007-12-27" cliente="769" local="77"/>
<reserva id="15239" data="2007-12-27" cliente="326" local="10"/>
</reservas>'
select
distinct reservas.reserva.value('@local[1]', 'int') as localfrom
@dados.nodes('/reservas/reserva') reservas(reserva)order
by localSolução 2
declare
@dados xmlset
@dados = '<reservas>
<reserva id="15232" data="2007-12-27" cliente="501" local="36"/>
<reserva id="15234" data="2007-12-27" cliente="609" local="49"/>
<reserva id="15237" data="2007-12-27" cliente="129" local="36"/>
<reserva id="15238" data="2007-12-27" cliente="769" local="77"/>
<reserva id="15239" data="2007-12-27" cliente="326" local="10"/>
</reservas>'
declare
@dadosaux xmlset
@dadosaux =(
select @dados.query('for $local in fn
istinct-values(/reservas/reserva/@local)
order by $local
return <local>{$local}</local>'
))select
reservas.reserva.value('text()[1]', 'int') as localfrom
@dadosaux.nodes('/local') reservas(reserva)Dizer qual é a mais performática é difícil. Se você tiver uma alta taxa de repetições, é bem provável que a segunda seja mais efetiva. Utilizar o DISTINCT da própria XQuery já retornará com um tempo menor. Não que a XQUERY seja mais ágil, mas é que retornar os resultados em forma de tabela já exigirá a XQUERY e adicionar o DISTINCT da XQUERY será melhor do que usar o DISTINCT da SQL. Se a taxa de repetições for baixa, é provável que o DISTINCT da SQL seja mais efetivo já que lidar com dados é algo que a SQL supera o comportamento procedural FLOWR da XQUERY.
Avaliei o plano de execução para o seu "template" e os resultados foram muito próximos. Talvez com uma carga maior, você possa ter um resultado mais preciso.
[ ]s,
Gustavo
Todas as Respostas
-
Eu esqueci o exemplo.
Code Blockdeclare
@dados xmlset
@dados = '<reservas>
<reserva id="15232" data="2007-12-27" cliente="501" local="36"/>
<reserva id="15234" data="2007-12-27" cliente="609" local="49"/>
<reserva id="15237" data="2007-12-27" cliente="129" local="36"/>
<reserva id="15238" data="2007-12-27" cliente="769" local="77"/>
<reserva id="15239" data="2007-12-27" cliente="326" local="10"/>
</reservas>'
Preciso retornar o local sem repetir, ou seja, 10, 36, 49 e 77. Tô usando o SQL 2005.
-
Boa Noite,
Existem duas formas de se fazer isso. Você pode optar por uma extração e aplicar um DISTINCT posteriormente ou utilizar a própria XQUERY para fazer esse filtro. Baseando-me no seu exemplo, seguem duas possíveis soluções:
Solução 1
declare @dados xml
set @dados = '
<reservas>
<reserva id="15232" data="2007-12-27" cliente="501" local="36"/>
<reserva id="15234" data="2007-12-27" cliente="609" local="49"/>
<reserva id="15237" data="2007-12-27" cliente="129" local="36"/>
<reserva id="15238" data="2007-12-27" cliente="769" local="77"/>
<reserva id="15239" data="2007-12-27" cliente="326" local="10"/>
</reservas>'
select
distinct reservas.reserva.value('@local[1]', 'int') as localfrom
@dados.nodes('/reservas/reserva') reservas(reserva)order
by localSolução 2
declare
@dados xmlset
@dados = '<reservas>
<reserva id="15232" data="2007-12-27" cliente="501" local="36"/>
<reserva id="15234" data="2007-12-27" cliente="609" local="49"/>
<reserva id="15237" data="2007-12-27" cliente="129" local="36"/>
<reserva id="15238" data="2007-12-27" cliente="769" local="77"/>
<reserva id="15239" data="2007-12-27" cliente="326" local="10"/>
</reservas>'
declare
@dadosaux xmlset
@dadosaux =(
select @dados.query('for $local in fn
istinct-values(/reservas/reserva/@local)
order by $local
return <local>{$local}</local>'
))select
reservas.reserva.value('text()[1]', 'int') as localfrom
@dadosaux.nodes('/local') reservas(reserva)Dizer qual é a mais performática é difícil. Se você tiver uma alta taxa de repetições, é bem provável que a segunda seja mais efetiva. Utilizar o DISTINCT da própria XQuery já retornará com um tempo menor. Não que a XQUERY seja mais ágil, mas é que retornar os resultados em forma de tabela já exigirá a XQUERY e adicionar o DISTINCT da XQUERY será melhor do que usar o DISTINCT da SQL. Se a taxa de repetições for baixa, é provável que o DISTINCT da SQL seja mais efetivo já que lidar com dados é algo que a SQL supera o comportamento procedural FLOWR da XQUERY.
Avaliei o plano de execução para o seu "template" e os resultados foram muito próximos. Talvez com uma carga maior, você possa ter um resultado mais preciso.
[ ]s,
Gustavo
-
-
Oi Marcos,
O OPENXML foi uma extensão que a Microsoft colocou no SQL Server 2000 com o intuito de dar algum suporte a XML. O projeto SQL Server 2000 (codinome Shiloh) iniciou-se logo após o lançamento do SQL Server 7 em meados de 1999 e nessa época o XML (embora antigo) ainda não havia se tornado o padrão que é hoje.
Com a crescente e irreversível utilização de XML e de seus padrões companheiros (XPath, XML Schema, XQuery, etc), o SQL Server 2005 fez melhoramentos muito consideráveis na utilização do XML. A extensão OPENXML ainda existe para não haver quebra da compatibilidade, mas você deve optar pelas construções e métodos mais novos (Nodes, Value, Exist, etc). Eles são mais seguros (não utilizam código não gerenciado nas XPs) e mais performáticos.
[ ]s,
Gustavo
-
-
-
Chapolin, o BOL tá com muitas informações, eu tenho estudado por ali, acho esse tópico de XML importantíssimo nos dias de hoje. É um padrão aberto e totalmente entendível entre plataformas.
http://technet.microsoft.com/en-us/library/ms345117.aspx
http://www.developer.com/db/article.php/3531196
http://www.linhadecodigo.com.br/Artigo.aspx?id=689
Abraços,
-
Bom Dia Chapolin,
Antigamente trabalhar com XML e o SQL Server era algo meio difícil e cheio de limitações. Quase sempre optávamos por controlar o XML na aplicação e deixar o formato relacional por conta do banco de dados. Embora alguns padrões XML tenham sido finalizados a pouco tempo (XQuery Jan/2007), o SQL Server 2005 incorporou os principais padrões XML com uma enorme compatibilidade com os publicados com o W3C.
Utilizar XML no SQL Server 2005, além de mais fácil, abre possibilidades que eram muito difíceis senão impossíveis. Tenho publicado diversos artigos sobre XML e SQL Server 2005 desde níveis mais básicos (tipo de dados XML) até níveis mais avançados (como fazer join entre dados XML). Em boa parte dos artigos coloquei scripts para o SQL Server 2005. Segue a relação abaixo:
Introdução a XPATH
http://www.plugmasters.com.br/sys/materias/384/1/Um-pouco-al%E9m-do-XML%3A-Introdu%E7%E3o-a-XPathIntrodução ao XML Schema
http://www.plugmasters.com.br/sys/materias/413/1/Um-pouco-além-do-XML:-Introdução-ao-XML-Schema-(XSD)---Parte-1
http://www.plugmasters.com.br/sys/materias/468/1/Um-pouco-além-do-XML:-Introdução-ao-XML-Schema-(XSD)---Parte-2
http://www.plugmasters.com.br/sys/materias/509/1/Um-pouco-além-do-XML:-Introdução-ao-XML-Schema-(XSD)---Parte-3
http://www.plugmasters.com.br/sys/materias/578/1/Um-pouco-além-do-XML:-Introdução-ao-XML-Schema-(XSD)---Parte-4
http://www.plugmasters.com.br/sys/materias/579/1/Um-pouco-além-do-XML:-Introdução-ao-XML-Schema-(XSD)---Parte-5A cláusula FOR XML
http://www.plugmasters.com.br/sys/materias/595/1/SQL-Server-2005-New-Features:-A-cláusula-FOR-XMLO tipo de dados XML
http://www.plugmasters.com.br/sys/materias/670/1/SQL-Server-2005-New-Features:-O-tipo-de-dados-XMLXML Schema Collection
http://www.plugmasters.com.br/sys/materias/747/1/SQL-Server-2005-New-Features:-XML-Schema-CollectionOs métodos XML
http://www.plugmasters.com.br/sys/materias/773/1/SQL-Server-2005-New-Features:-Os-métodos-XML---Parte-1
http://www.plugmasters.com.br/sys/materias/799/1/SQL-Server-2005-New-Features:-Os-métodos-XML---Parte-2Acredito que você os achará interessantes.
[ ]s,
Gustavo
-
-