I am trying to select from SQL Server 2005 XML datatype some values based on the max data that is located in a child node.
I have multiple rows with XML similar to the following stored in a field in 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>
I want to perform a select from this XML column where it determines the max date within the token element and would return the datarows similar to the result below for each record:
Joe XYZ456 2014-01-01 18:48:50.111
I have tried to find a max function for xpath that would all me to select the correct token element but I couldn't find one that would work.
I also tried to use the SQL MAX function but I wasn't able to get it working with that method either.
If I only have a single token it of course works fine but when I have more than one I get a NULL, most likely because the query doesn't know which date to pull. I was hoping there would be a 开发者_如何学Pythonway to specify a where clause [max(endDate)]
on the token element but haven't found a way to do that.
Here is an example of the one that works when I only have a single token:
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
How about this:
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
You basically take the "atomic" part like 'UserName' directly from the XML, and then cross apply a list of /user/token and extract the individual bits you want - you get a result set of three columns (UserName, ID, EndDate) and you can order and filter those.
Side note: instead of this:
XMLCOL.query('user/name').value('.','NVARCHAR(20)')
why don't you use this - feels much easier!
XMLCOL.value('(/user/name)[1]', 'NVARCHAR(20)')
精彩评论