2010-06-17 7 views
2

J'essaie de sélectionner à partir du type de données XML SQL Server 2005 des valeurs basées sur les données max situées dans un nœud enfant.Sélection d'un nœud XML dans SQL Server en fonction de la valeur maximale d'un élément enfant

J'ai plusieurs lignes avec XML semblable au suivant stocké dans un champ dans SQL Server:

<user> 
    <name>Joe</name> 
     <token> 
     <id>ABC123</id> 
     <endDate>2013-06-16 18:48:50.111</endDate> 
     </token> 
     <token> 
     <id>XYX456</id> 
     <endDate>2014-01-01 18:48:50.111</endDate> 
     </token> 
</user> 

Je veux effectuer une sélection de cette colonne XML où il détermine la date maximum dans l'élément jeton et renverrait les lignes de données similaires au résultat ci-dessous pour chaque enregistrement:

Joe XYZ456 01/01/2014 18: 48: 50,111

J'ai essayé de trouver une fonction max pour xpath qui serait tout pour moi de sélectionner l'élément de jeton correct mais je ne pouvais pas trouver celui qui fonctionnerait.

J'ai également essayé d'utiliser la fonction SQL MAX mais je n'ai pas réussi à l'utiliser avec cette méthode non plus.

Si je n'ai qu'un seul jeton, cela fonctionne bien, mais quand j'en ai plusieurs, j'ai une valeur NULL, probablement parce que la requête ne sait pas quelle date tirer. J'espérais qu'il y aurait un moyen de spécifier une clause where [max(endDate)] sur l'élément de jeton mais n'a pas trouvé un moyen de le faire.

Voici un exemple de celui qui fonctionne quand je n'ai qu'un seul jeton:

SELECT 
XMLCOL.query('user/name').value('.','NVARCHAR(20)') as name 
XMLCOL.query('user/token/id').value('.','NVARCHAR(20)') as id 
XMLCOL.query('user/token/endDate').value(,'xs:datetime(.)','DATETIME') as endDate 
FROM MYTABLE 

Répondre

3

Que diriez-vous ceci:

SELECT 
    TOP 1 
    XMLCOL.value('(/user/name)[1]', 'nvarchar(20)') as 'UserName', 
    Usr.Token.value('(id)[1]', 'nvarchar(20)') AS 'ID', 
    Usr.Token.value('(endDate)[1]', 'DateTime') as 'EndDate' 
FROM 
    dbo.MyTable 
CROSS APPLY 
    xmlcol.nodes('/user/token') AS Usr(Token) 
ORDER BY 
    Usr.Token.value('(endDate)[1]', 'DateTime') DESC 

Vous prenez essentiellement la partie « atomique » comme « UserName 'directement à partir du XML, et ensuite appliquer une liste de/user/token et extraire les bits individuels que vous voulez - vous obtenez un ensemble de résultats de trois colonnes (UserName, ID, EndDate) et vous pouvez les commander et les filtrer.

Side note: au lieu de ceci:

XMLCOL.query('user/name').value('.','NVARCHAR(20)') 

pourquoi utilisez-vous pas - se sent beaucoup plus facile!

XMLCOL.value('(/user/name)[1]', 'NVARCHAR(20)') 
+0

Le CROSS APPLY a fait l'affaire. Ce n'était pas exactement ce dont j'avais besoin mais vous m'avez indiqué dans la bonne direction. Merci. – Jay

Questions connexes