我偶然发现了一个随机代码ID生成器,我无法弄清楚它是如何工作的。
SELECT TOP (5) c1
FROM
(
VALUES
('A'), ('B'), ('C'), ('D'), ('E'), ('F'), ('G'),
('3'), ('4'), ('5'), ('6'), ('7'), ('8'), ('9')
) AS T1(c1)
ORDER BY ABS(CHECKSUM(NEWID()))
我看过以下内容:
如果我然后尝试做“按2089106226排序”,它显然会失败
那么什么是“ABS(CHECKSUM(NEWID())”返回以及这种类型的排序叫什么?
答案 0 :(得分:5)
ORDER BY
子句不必像您发现的那样对特定列进行排序,而是可以包含任意表达式。我不相信这有任何特殊名称,它只是order_by_expression
documented here
ORDER BY
部分中的动态值
ORDER BY
中的非列表达式可能类似于
ORDER BY a_column % 5
根据列的值模数5或类似
对行进行排序ORDER BY CASE WHEN LEFT(a_column, 1) = 'Z' THEN 0 ELSE 1 END ASC, a_column ASC
强制column
以Z
开头的所有值排在所有其他值之前,但在其他方面是按字母顺序排列的,方法是将0
归为Z
行{ {1}}否则(其中零排序)。
在这种情况下,表达式是在T-SQL中随机化行顺序的常用方法:
1
将为ABS(CHECKSUM(NEWID()))
语句返回的每一行调用NEWID()
函数,这会产生5个单独的GUID值。从那里,这5个中的每一个都是passed to CHECKSUM()
,它返回一个恰好是整数的索引哈希值。 SELECT
最终迫使它成为一个正整数。
因此,最终发送到ABS()
的值只是从多个ORDER BY
调用派生的整数列表,而NEWID()
排序整数没有问题。最后,它与排序整数值列并没有什么不同 - 只是这些是在查询时生成的。
如果您运行this demonstration on SQLFiddle几次,则会在每次执行时为其他增量ORDER BY
获得不同的排序顺序。因此,看起来有问题的随机代码生成器SQL的作者使用id
来混淆从ORDER BY
列表中选择的5个字符的随机集合的原因。如果您run the code generator SQL并注释掉VALUES ()
,则会始终返回行集ORDER BY
。在A,B,C,D,E
到位后,它会返回一个随机集。
答案 1 :(得分:0)
我看了http://technet.microsoft.com/en-us/library/ms188385.aspx
但是从语法上我看不出它是如何工作的
ORDER BY order_by_expression
[ COLLATE collation_name ]
[ ASC | DESC ]
[ ,...n ]
[ <offset_fetch> ]
<offset_fetch> ::=
{
OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS }
[
FETCH { FIRST | NEXT } {integer_constant | fetch_row_count_expression } { ROW | ROWS } ONLY
]
}