Какво ще кажете за това:
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)')