Apparently, the query engine computes a random number twice for each row.
The first time for Col1 , the second time for the CASE statement of a saved column.
The optimizer does not know or care in this case that NEWID is a non-deterministic function and calls it twice.
Actually, he may not even have a choice. Do you want the optimizer to create a temporary table behind the scenes, populate Col1 results of an expression that generates random numbers, then read this temporary table and use these stored intermediate results to calculate the result of the CASE expression, then do the final INSERT ? In this case, the optimizer is cheaper to calculate the expression twice without writing intermediate results to disk. In some other cases (for example, if you do not have 5, but 5 billion rows or additional indexes), the estimated costs can be different, and this behavior will change.
I donβt think you can do much. Just be aware of this behavior. Always explicitly save the generated set of random numbers to a table, and then perform further calculations based on them.
I reproduced it in SQL Server 2008 and 2014. Here is the execution plan that I got in SQL Server 2008, but it is not very interesting. In 2014, the plan is the same, except for the Top operator.

Operator
Constant Scan lists Union1009 , which is used by Compute Scalar later. I think it comes down to the implementation details of the Constant Scan and / or Compute Scalar operators.
The observed behavior tells us that newid() is called here twice on a line.
Vladimir Baranov
source share