我正在查看postgres问题并且它要求使用随机值更新表。
我只是注意到它在回答之后就是以postgres为目标,但在回答它时我发现了一个谜。
以下是我的问题示例代码:
create table #Buildings([Use] varchar(50), n int)
insert #Buildings
select null,null from sysobjects
update #Buildings
set [Use] =
case (ABS(CAST(CAST(NEWID() AS VARBINARY) AS int)) % 6)
when 0 then null
when 1 then 'warehouse'
when 2 then 'office'
when 3 then 'market'
when 4 then 'retail'
when 5 then 'workshop'
else 'HOW IS THIS POSSIBLE'
end,
n = ABS(CAST(CAST(NEWID() AS VARBINARY) AS int)) % 6
select [Use], count(*) from
#Buildings
group by [Use]
select n, count(*) from
#Buildings
group by n
它返回一个非常奇怪的结果集:
Use
-------------------------------------------------- -----------
workshop 128
HOW IS THIS POSSIBLE 633
NULL 287
retail 140
warehouse 258
market 177
office 209
第二个完全合理的结果集:
n
----------- -----------
0 292
3 300
1 313
4 277
5 311
2 339
两个结果集的数据都在同一个更新语句中生成。
所以我的问题是为什么一个超出0-5范围的数字命中我的案例陈述?这个数字是多少?为什么我直接更新int是正确分配的东西?
答案 0 :(得分:5)
我有个主意:
也许在每个when语句上计算值,如果它到达第一个,计算一个非0的值,它到第二个,然后计算一个非1的值,然后是下一个,依此类推,如果它使它达到5,然后计算5以外的数字,那么它就转到了其他地方。
这也可以解释为什么还有比其他更多的“如何可能”,当当前位置和该位置产生的随机数匹配时,其他的会增加。
你的想法?
编辑:我也在sql server express 2008中进行了测试,结果相同。
答案 1 :(得分:1)
create table #Buildings([Use] varchar(50), n int)
insert #Buildings
select null,null from sysobjects
declare @i int
update #Buildings
set
@i = (ABS(CAST(CAST(NEWID() AS VARBINARY) AS int)) % 6),
[Use] =
case @i -- if the expression is evaluated on-the-fly for each WHEN, MSSQL variable-in-SQL capability will alleviate this problem
when 0 then null
when 1 then 'warehouse'
when 2 then 'office'
when 3 then 'market'
when 4 then 'retail'
when 5 then 'workshop'
else 'HOW IS THIS POSSIBLE'
end,
n = @i
select [Use], count(*) from
#Buildings
group by [Use]
select n, count(*) from
#Buildings
group by n
答案 2 :(得分:0)
约翰可能是对的...虽然担心“什么时候”会如此低效。
另请注意,NewId()函数每次调用时都会返回一个新值。你打电话给它两次(不计算“什么时候”的怪癖)。以下更稳定: 删除表#Buildings 去
create table #Buildings([Use] varchar(50),n int)
插入#Buildings 从sysobjects中选择null,null
将@nid声明为uniqueidentifier
更新#Buildings 设置@nid = newid(), [使用] = case(ABS(CAST(CAST(NewId()AS VARBINARY)AS int))%6) 当0然后为null 当1然后'仓库' 当2然后'办公室' 当3然后'市场' 当4然后'零售' 当5然后'工作坊' 别的'这怎么可能' 结束, n = ABS(CAST(CAST(NewId()AS VARBINARY)AS int))%6
从
中选择[使用],计数(*)按[使用]分组
从
中选择n,count(*)分组n