While running a modulo function inside a case statement, there are many times that a value outside of the expected range is returned.
SELECT CASE WHEN ABS(CheckSUM(NewId())) % 5 IN (0,1,2,3,4) then NULL
ELSE 'What Happened?' END
If you run this script a few times, you will see there are times that the result appears to be outside of the range of 0,1,2,3,4. My thinking is that this is somehow returning non-integer values during the case statement causing modulo to be an ineffective method of sorting by case.
Could someone explain what is happening in these cases so that I can combat this in the future?
NOTE: If I run the code modulo function by itself (outside of case statement) and return the results all values are in the range of 0,1,2,3,4 as expected.
Returns the remainder of one number divided by another.
To compute the absolute value of a number, use the ABS() function. This function takes a number as an argument and returns its value without the minus sign if there is one. The returned value will always be non-negative – zero for argument 0, positive for any other argument.
The MOD function in standard query language (SQL) takes two arguments of numeric data type, the first argument as dividend and second argument as divisor and returns the remainder or modulus after performing a division operation or repeated subtraction. It is similar to REMAINDER and FLOOR functions.
Change your statement to
SELECT top(1)
CASE WHEN ABS(CheckSUM(NewId())) % 5 IN (0,1,2,3,4) then NULL
ELSE 'What Happened?' END
And have a look at the actual execution plan.
The IN
part in the case is expanded to.
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
abs(checksum(newid()))%(5)
is executed once for each value in the in clause.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With