Выберите узел XML в SQL Server на основе максимального значения дочернего элемента - PullRequest
2 голосов
/ 17 июня 2010

Я пытаюсь выбрать из типа данных SQL Server 2005 XML некоторые значения, основанные на максимальных данных, которые находятся в дочернем узле.

У меня есть несколько строк с XML, аналогичных приведенным ниже, которые хранятся в поле в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>

Я хочу выполнить выбор из этого столбца XML, где он определяет максимальную дату в элементе токена и возвращает значения datarow, аналогичные приведенному ниже результату для каждой записи:

Джо XYZ456 2014-01-01 18: 48: 50.111

Я попытался найти функцию max для xpath, которая позволила бы мне выбрать правильный элемент токена, но я не смогя не смог найти такую, которая бы работала.

Я также пытался использовать функцию SQL MAX, но я также не смог заставить ее работать с этим методом.

Если у меня только один токенэто, конечно, работает нормально, но когда у меня их больше одного, я получаю NULL, скорее всего, потому что запрос не знает, какую дату получить.Я надеялся, что найдется способ указать выражение where [max(endDate)] для элемента токена, но я не нашел способа сделать это.

Вот пример того, который работает, когда у меня есть толькоодин токен:

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

1 Ответ

3 голосов
/ 17 июня 2010

Как насчет этого:

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

В основном вы берете «атомарную» часть, такую ​​как «UserName», непосредственно из XML, а затем перекрестно применяете список / user / token и извлекаете нужные вам биты - вы получаете результирующий набор из трех столбцов (UserName, ID, EndDate), и вы можете заказать и отфильтровать их.

Примечание: вместо этого:

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

почему бы вам не использовать это - чувствует себя намного проще!

XMLCOL.value('(/user/name)[1]', 'NVARCHAR(20)') 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...