SQL Server模数函数似乎返回超出预期范围的值

rdb*_*haw 6 sql-server modulo

在case语句中运行模数函数时,很多时候会返回超出预期范围的值.

SELECT CASE WHEN ABS(CheckSUM(NewId())) % 5 IN (0,1,2,3,4) then NULL 
       ELSE 'What Happened?' END 
Run Code Online (Sandbox Code Playgroud)

如果您运行此脚本几次,您将看到有时候结果似乎超出了0,1,2,3,4的范围.我的想法是,在case语句中,这会以某种方式返回非整数值,从而导致modulo成为一种无效的按案例排序的方法.

有人可以解释这些案件中发生的事情,以便我将来可以解决这个问题吗?

注意:如果我自己运行代码模数函数(在case语句之外)并返回结果,则所有值都在预期的0,1,2,3,4范围内.

Mik*_*son 6

将您的陈述更改为

SELECT top(1)
 CASE WHEN ABS(CheckSUM(NewId())) % 5 IN (0,1,2,3,4) then NULL 
       ELSE 'What Happened?' END 
Run Code Online (Sandbox Code Playgroud)

并查看实际的执行计划.

IN案件中的部分扩展为.

CASE WHEN abs(checksum(newid()))%(5)=(4) OR 
          abs(checksum(newid()))%(5)=(3) OR 
          abs(checksum(newid()))%(5)=(2) OR 
          abs(checksum(newid()))%(5)=(1) OR 
          abs(checksum(newid()))%(5)=(0) 
  THEN NULL 
  ELSE 'What Happened?' 
END
Run Code Online (Sandbox Code Playgroud)

abs(checksum(newid()))%(5) 对于in子句中的每个值执行一次.