【问题标题】:How does ORDER BY ABS(CHECKSUM(NEWID())) work?ORDER BY ABS(CHECKSUM(NEWID())) 是如何工作的?
【发布时间】:2014-02-27 00:26:10
【问题描述】:

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

我看过以下内容:

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

如果我然后尝试执行“2089106226 订购”,它显然会失败

那么“ABS(CHECKSUM(NEWID()))”返回的是什么,这种排序方式又叫什么?

【问题讨论】:

    标签: sql sql-server sql-order-by


    【解决方案1】:

    ORDER BY 子句不必像您发现的那样对特定列进行排序,而是可以包含任意表达式。我不相信这有什么特别的名字,它只是ORDER BYdocumented hereorder_by_expression部分中的一个动态值

    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 分配给其他值(其中0 排在前面一个)。

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

    ABS(CHECKSUM(NEWID()))
    

    将为SELECT 语句返回的每一行调用NEWID() 函数,这会产生5 个单独的GUID 值。从那里开始,这 5 个中的每一个都是 passed to CHECKSUM(),它返回一个恰好是整数的索引哈希值。 ABS() 最终强制为正整数。

    所以最终发送到ORDER BY 的值只是从多次调用NEWID() 派生的整数列表,ORDER BY 对整数进行排序没有问题。最后,它与对一列整数值进行排序并没有什么不同——只是这些是在查询时生成的。

    如果您多次运行this demonstration on SQLFiddle,您将获得不同的排序顺序,否则每次执行时递增的id。所以看起来有问题的随机代码生成器 SQL 的作者使用 ORDER BY 的原因是随机排列从 VALUES () 列表中选择的 5 个字符。如果您run the code generator SQL 并注释掉ORDER BY,它将始终返回行集A,B,C,D,E。使用 ORDER BY 后,它会返回一个随机集。

    【讨论】:

    • 感谢您花时间和精力回答这个问题。让我困惑的是查询时的顺序。
    【解决方案2】:

    我看了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
        ]
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-21
      相关资源
      最近更新 更多