ORDER BY ABS(CHECKSUM(NEWID())如何运作?

Ber*_*ger 3 sql sql-server sql-order-by

我偶然发现了一个随机代码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()))
Run Code Online (Sandbox Code Playgroud)

我看过以下内容:

  • 选择NEWID() - > E8E142CC-A918-4776-AA99-2D33DC80FE28
  • 选择CHECKSUM('E8E142CC-A918-4776-AA99-2D33DC80FE28') - > -2089106226
  • 选择ABS(-2089106226) - > 2089106226

如果我然后尝试做"2089106226的订单",它显然会失败

那么什么是"ABS(CHECKSUM(NEWID())"返回以及这种类型的排序叫什么?

Mic*_*ski 5

ORDER BY条款不具有排序特定列如你发现的,而是它可以包含任意表达式.我不相信这有任何特殊的名称,它只是这里记录order_by_expression部分的动态值ORDER BY

ORDER BY可能是类似的非列表达式

ORDER BY a_column % 5
Run Code Online (Sandbox Code Playgroud)

根据列的值模数5或类似情况对行进行排序

ORDER BY CASE WHEN LEFT(a_column, 1) = 'Z' THEN 0 ELSE 1 END ASC, a_column ASC
Run Code Online (Sandbox Code Playgroud)

以迫使所有的值column开始与Z 排序领先于所有其他的,但在其他方面是字母,由一个归咎于0Z行和1以其他方式(其中领先的零级排序).

在这种情况下,表达式是在T-SQL中随机化行顺序的常用方法:

ABS(CHECKSUM(NEWID()))
Run Code Online (Sandbox Code Playgroud)

NEWID()将为SELECT语句返回的每一行调用该函数,这将产生5个单独的GUID值.从那里,传递给CHECKSUM()那些5中的每一个返回索引散列值,该索引散列值恰好是整数. ABS()最后迫使它成为一个正整数.

因此,最终发送到的ORDER BY值只是从多次调用派生的整数列表NEWID(),并且ORDER BY排序整数没有问题.最后它与排序整数值列并没有什么不同 - 只是这些是在查询时生成的.

如果你在SQLFiddle上运行这个演示几次,你会得到一个不同的排序顺序,否则id每次执行都会增加.所以看起来所使用的随机代码生成器SQL的作者使用的原因ORDER BY是随机抽取从VALUES ()列表中选择的5个字符的集合.如果您运行代码生成器SQL并注释掉ORDER BY它,它将始终返回行集A,B,C,D,E.随着ORDER BY它,它返回一个随机集.