简体   繁体   中英

Can you use random numbers in a CASE statement (SQL Server 2016)

I have tried to construct a CASE statement that will fit into a larger SELECT. I want each row to resolve separately (using a different random number per row) but for the random number to be the same when evaluating the case statement within a particular row if that makes sense.

I have tried

    SELECT 
    [Player name]
    ,[Stake]
    ,[current jackpot]

         ,CASE

         WHEN 
         rand() < 0.23
         THEN
         'Win'
         WHEN
         rand() BETWEEN 0.23 AND 0.89
         then
         'Lose'
         when
         rand() >= 0.89
         then
         'Jackpot'
         else
         'other'
         end as [outcome]
...

but the fact that I sometimes get an 'other' result tells me that each WHEN is creating a different random number to evaluate. I also can't declare a global random number at the start and use that because each line should resolve separately.

You can . However, rand() is evaluated only once per query, not once per row. Instead, you want to do something with newid() . However, because you reference the value multiple times in the CASE , this poses a challenge. One method is:

SELECT . . .
        (CASE WHEN rnd < 0.23 THEN 'Win'
              WHEN rnd < 0.89 THEN 'Lose'
              WHEN rnd >= 0.89 THEN 'Jackpot'
              ELSE 'Other' -- impossible
         END) as [outcome]
FROM (SELECT t.*, rand(convert(varbinary, newid())) as rnd
      FROM t
     ) t

Each time you call RAND() , a random seed is given since you didn't specify one. Just give RAND() a seed and it will remain the same.

select 
    case when 1 = 1 then rand(4) end
    ,case when 2=2 then rand(4) end

Or use a column value...

select 
    case when 1 = 1 then rand(someColumn) end
    ,case when 2=2 then rand(someColumn) end

Another option is with a Cross Apply

Example

Select [Player name]
      ,[Stake]
      ,[current jackpot]
      ,[OutCome] = case when b.randV<0.23 then 'win'
                        when b.randV between 0.23 and 0.89 then 'lose'
                        when b.randV>=0.89 then 'Jackpot'
                        else 'other' end
 From  YourTable
 Cross Apply (values (rand(cast( NewID() as varbinary )))) B(randV)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM