Questions About Sort Order Using XQuery in SQL Server

南楼画角 提交于 2019-12-07 18:52:07

问题


Is the result of a SELECT like the one below using XQuery in SQL Server guaranteed to be in document order, that is in the original order the nodes are listed in the xml string?

DECLARE @x XML = '<hey i="3"/><hey i="4"/><hey i="0"/>'
SELECT t.i.value('.', 'int')
FROM @x.nodes('/hey/@i') t(i)

I ask because in general SELECT statements do not guarantee an order unless one is provided.

Also, if this order is (or is not) guaranteed, is that documented somewhere officially, maybe on Microsoft's web site?

Last, is it possible to sort opposite of document order or do other strange sorts and queries based on the original document order from within the SELECT statement?


回答1:


The DECLARE @x XML = '<hey i="3"/><hey i="4"/><hey i="0"/>' is an example of an XML "sequence". By definition, without a sort order, the select should always come back in the documents original order.

As already mentioned, you can change the sort order. Here is one example:

SELECT t.i.value('.', 'int') as x, ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) as rn

FROM @x.nodes('/hey/@i') t(i)

order by rn desc

Here is some information about sequences on the Microsoft site:

http://msdn.microsoft.com/en-us/library/ms179215(v=sql.105).aspx

Here is a more general discussion of a sequence in Xquery.

http://en.wikibooks.org/wiki/XQuery/Sequences


I realize that my original answer above is incorrect after reading the page on the Microsoft site I referred to above. That page says that you need a comma between elements to construct a sequence. The example given is not a "sequence". However, my original info about changing the sort order stands :)




回答2:


I think that same rules of Select apply here, no matter if you're selectig from ordinary table, or XML. There's selection part, and there's projection part, and the engine can take different paths to retrieve your data (from the middle sideways, for example). Unfortunately I can't find any official document to support that. And for sure, there's no intrinsic table/document order that you can access and manipulate.




回答3:


You can add order by clause to the select statement.

DECLARE @x XML = '<hey i="3"/><hey i="4"/><hey i="0"/>'SELECT [column1] = t.i.value('.', 'int') FROM @x.nodes('/hey/@i') t(i)  order by column1 desc



回答4:


I know what you mean about this. I suspect the order would be document order, but the documentation does not make it clear, and relying on it implicitly just isn't nice.

One way to be confident about the order would be:

DECLARE @x XML = '<hey i="3"/><hey i="4"/><hey i="0"/>';
select @x.value('(/hey[sql:column("id")]/@i)[1]', 'int'), id
from (
    select row_number() over (order by (select 0)) as id
    from @x.nodes('/hey') t(i)
) t
order by id

This would then give you a way to answer your other question, i.e. getting the values in reverse, or some other, order.

N.B. This is going to be much slower than just using nodes as the size of your XML increases.



来源:https://stackoverflow.com/questions/15258516/questions-about-sort-order-using-xquery-in-sql-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!