我正在寻找“ORDER BY RAND()”和“ORDER BY NEWID()”的官方T-SQL文档。 有很多文章描述它们,所以必须在某处记录它们。
我正在寻找指向官方SQL Server文档页面的链接,如下所示:http://technet.microsoft.com/en-us/library/ms188385.aspx
澄清:
我正在寻找的是“order_by_expression”的文档,它解释了非负整数常量,返回非负整数的函数和返回任何其他值的函数(如RAND()或NEWID())。
答:
我为我原来的问题缺乏明确性而道歉。与大多数与编程相关的问题一样,问题的解决方案主要是找出你实际想要回答的问题
谢谢大家。
答案在本文件中:来自:http://www.wiscorp.com/sql200n.zip
Information technology — Database languages — SQL — Part 2: Foundation (SQL/Foundation)
22.2 <direct select statement: multiple rows> includes a <cursor specification>.
此时我们有答案的前半部分:
SELECT语句是一种CURSOR,这意味着可以在每一行上迭代执行操作。虽然我没有在明确说明的文档中找到声明,但我很乐意假设order_by_expression中的表达式将针对每一行执行。
现在,当使用RAND()或NEWID()或CEILING(RAND()+ .5)/ 2而不是数字常量或列名时,会发生什么事情。
表达式永远不会被视为列号。它将始终是为每行生成的值,它将用作确定行顺序的基础
但是,为了彻底性,让我们继续完整定义表达式可以是什么。
14.3 <cursor specification> includes ORDER BY <sort specification list>.
10.10 <sort specification list> defines:
<sort specification> ::= <sort key> [ <ordering specification> ] [ <null ordering> ]
<sort key> ::= <value expression>
<ordering specification> ::= ASC | DESC
<null ordering> ::= NULLS FIRST | NULLS LAST
带我们去:
6.25 <value expression>
我们找到答案的后半部分:
<value expression> ::=
<common value expression>
| <boolean value expression>
| <row value expression>
<common value expression> ::=
<numeric value expression>
| <string value expression>
| <datetime value expression>
| <interval value expression>
| <user-defined type value expression>
| <reference value expression>
| <collection value expression>
<user-defined type value expression> ::= <value expression primary>
<reference value expression> ::= <value expression primary>
<collection value expression> ::= <array value expression> | <multiset value expression>
从这里我们可以看到可以使用的众多可能类型的表达式
NEWID()返回一个uniqueidentifier
假设uniqueidentifier在数字上进行比较似乎是合理的,因此如果表达式是NEWID(),则我们的&lt;公共值表达式&gt;将是&lt;数值表达式&gt;
同样,RAND()返回一个数值,它也将被评估为&lt;数值表达式&gt;。
因此,虽然我无法在Microsoft的官方文档中找到任何解释使用作为表达式的order_by_expression调用的ORDER BY所做的事情,但它确实已经记录,因为我知道它必须是。
答案 0 :(得分:8)
如果你试图确定为什么这些行为不同,原因很简单:一个被评估一次,被视为运行时常量(RAND()
),而另一个被评估为每一行({ {1}})。请注意这个简单的例子:
NEWID()
结果:
SELECT TOP (5) RAND(), NEWID() FROM sys.objects;
现在,如果您将订单应用到左列,SQL Server说,好的,但每个值都相同,所以我基本上只是忽略您的请求并转到下一个ORDER BY列。如果没有,则SQL Server将默认以其认为最有效的顺序返回行。
如果您将订单应用到右栏,那么现在SQL Server实际上必须对所有值进行排序。这会在计划中引入0.240705716465209 8D5D2B55-E5DE-4FF9-BA84-BC82F37B8F3A
0.240705716465209 C4CBF1CA-E6D0-4076-B6A6-5048EA612048
0.240705716465209 9BFAE5BB-B5B9-47DE-B8F9-77AAEFA5F9DB
0.240705716465209 89FFD8A1-AC73-4CEB-A5C0-00A76D040382
0.240705716465209 BCC89923-735E-43B3-9ECA-622A8C98AD7D
(或Sort
,如果使用TopN Sort
)运算符,并且可能会占用更多CPU(尽管总体持续时间可能不会受到太大影响,具体取决于集合的大小和其他因素)。
让我们比较这两个查询的计划:
TOP
计划:
没有排序运算符,并且两个扫描都是SELECT RAND() FROM sys.all_columns ORDER BY RAND();
- 这意味着SQL Server尚未决定显式实现任何排序,但这肯定不意味着每次执行时订单都会有所不同 - 这只是意味着订单是非确定性的(除非您添加辅助Ordered = False
- 但即使在这种情况下,ORDER BY
排序仍然会被忽略,因为好吧,它在每一行都是相同的值。)
现在RAND()
:
NEWID()
计划:
那里有一个新的SELECT NEWID() FROM sys.all_columns ORDER BY NEWID();
运算符,这意味着SQL Server必须按照每行上生成的GUID值的顺序重新排序要返回的所有行。当然扫描仍然是无序的,但Sort
最终会应用订单。
我不知道这个具体的实现细节是在任何地方正式记录的,但我确实发现this article包含一个明确的Sort
。我怀疑你会发现任何以任何方式记录ORDER BY NEWID()
的官方文件,因为这没有任何意义,官方支持与否。
Re:SQL Server分配的注释ORDER BY RAND()
- 这不应该被解释为a seed value at random
。示范:
a seed value **per row** at random
结果:
SELECT MAX(r), MIN(r) FROM
(
SELECT RAND() FROM sys.all_columns AS s1
CROSS JOIN sys.all_columns AS s2
) AS x(r);
在我的计算机上,这需要大约15秒才能运行,0.4866202638872 0.4866202638872
和MIN
的结果始终相同。继续增加返回的行数和所花费的时间,我保证您将继续在每一行上看到MAX
的完全相同的值。它只计算一次,这不是因为SQL Server明智的是我没有返回所有的行。这也产生了相同的结果(用不到2分钟的时间用整个表填充7200万行):
RAND()
(实际上SELECT RAND() AS r INTO #x
FROM sys.all_columns AS s1
CROSS JOIN sys.all_columns AS s2
CROSS JOIN sys.all_columns AS s3;
SELECT MAX(r), MIN(r) FROM #x;
的使用时间几乎和初始人口一样长。请不要在配备4GB RAM的单核笔记本电脑上试试这个。)
结果:
SELECT
答案 1 :(得分:2)
查看以下链接。
ORDER BY,RAND和NEWID是TSQL语言的语句和函数。
将它们组合起来随机选择或生成数据是一种设计模式。
参见前两篇文章。
生成无冲突的随机整数
http://www.sqlperformance.com/2013/09/t-sql-queries/random-collisions
MSDN - 从大表中随机选择行
http://msdn.microsoft.com/en-us/library/cc441928.aspx
MSDN - RAND
http://technet.microsoft.com/en-us/library/ms177610.aspx
MSDN - NEWID
http://msdn.microsoft.com/fr-fr/library/ms190348.aspx
MSDN - ORDER BY
http://technet.microsoft.com/en-us/library/ms188385.aspx
非常好读Aaron。
但是,另外,单独采用(RAND,NEWID,ORDER BY)是元素是TSQL语言的一部分。
使用它们随机选择数据是设计模式。
此外,您可以在while循环中调用RAND() - RBAR()生成随机数。
这是因为在查询计划中,RAND()不再是常量。
-- RBAR solution
declare @x float = 0;
declare @y int = 0;
while (@y < 100)
begin
set @x = rand();
print @x;
set @y += 1;
end;
go
答案 2 :(得分:2)
如果我们成为细节的坚持者,那么你提出的问题基本上就是“哪里的文档为〜”。答案是无处可去的,没有像您正在寻找的那样的文档。
无论如何,有多个文档分别处理NEWID(),RAND()和ORDER BY,你必须自己把它们放在一起。
基本上,
这让你知道它是有效的语法,但没有一个链接供你指出。