Que tal agora:
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
Você basicamente pega a parte "atômica" como 'UserName' diretamente do XML e, em seguida, aplica uma lista de /user/token e extrai os bits individuais que deseja - você obtém um conjunto de resultados de três colunas (UserName, ID, EndDate ) e você pode ordená-los e filtrá-los.
Nota lateral:em vez disso:
XMLCOL.query('user/name').value('.','NVARCHAR(20)')
por que você não usa isso - parece muito mais fácil!
XMLCOL.value('(/user/name)[1]', 'NVARCHAR(20)')