我尝试使用以下语句从另一个表中随机填充列:
UPDATE dbo.SERVICE_TICKET
SET Vehicle_Type = (SELECT TOP 1 [text]
FROM dbo.vehicle_typ
WHERE id = abs(checksum(NewID()))%21)
似乎工作正常,但值NULL
已插入列中。如何摆脱NULL
并仅插入表中的值?
答案 0 :(得分:2)
如果您在ID
表的vehicle_typ
列上没有相应的索引,就会发生这种情况。这是一个较小的查询,表现出同样的问题:
create table T (ID int null)
insert into T(ID) values (0),(1),(2),(3)
select top 1 * from T where ID = abs(checksum(NewID()))%3
因为T
上没有索引,所以会发生什么是SQL Server执行表扫描,然后,对于每一行,尝试满足where子句。这意味着,对于每个行,它会重新评估abs(checksum(NewID()))%3
。只有当{/ 1}} 评估1
1行时,您才会得到一个结果。
如果可能(我不知道你的表格结构)我会首先填充ID
中的一列,其中0到20之间的随机数和然后< / em>使用已生成的数字执行此更新。否则,使用当前的查询结构,您始终依赖SQL Server足够聪明,只能为每个外行评估SERVICE_TICKET
一次,这可能并不总是如此(因为您已经找到了)出)。
答案 1 :(得分:1)
@Damien_The_Unbeliever解释了您的查询失败的原因。
我的第一个变体不正确,因为我没有完全理解这个问题。
您希望将SERVICE_TICKET
中的每一行设置为vehicle_typ
的其他随机值。
要修复它,只需按随机数排序,而不是将随机数与ID
进行比较。像这样(只要在那里至少有一行,你就不在乎vehicle_typ
中有多少行。)
WITH
CTE
AS
(
SELECT
dbo.SERVICE_TICKET.Vehicle_Type
CA.[text]
FROM
dbo.SERVICE_TICKET
CROSS APPLY
(
SELECT TOP 1 [text]
FROM dbo.vehicle_typ
ORDER BY NewID()
) AS CA
)
UPDATE CTE
SET Vehicle_Type = [text];
首先我们创建一个公用表表达式,您可以将其视为临时表。对于SERVICE_TICKET
中的每一行,我们使用vehicle_typ
从CROSS APPLY
中选择一个随机行。然后我们UPDATE
选择行的原始表。