使用列表中的新值随机替换表中的现有值。

问题描述 投票:1回答:2

简单的桌子

    Date       |ChannelID 

    01/01/2001 | 1001
    02/01/2001 | 1001
    03/01/2001 | 1001
    04/01/2001 | 1001
    05/01/2001 | 1001
    06/01/2001 | 1001

我需要在每一行上随机替换为1001,2001或2002的ChannelID值。

我尝试过以下操作,但似乎没有给我随机输入,并因某种原因错过了最后一个值。

    update A

set ChannelID = (
    SELECT TOP 1 b.q
    FROM (
        SELECT 1001 AS q

        UNION ALL

        SELECT 2001

        UNION ALL

        SELECT 2002
        ) b
        CROSS APPLY (
  SELECT TOP 1 b2.q2
    FROM (
        SELECT 1001 AS q2

        UNION ALL

        SELECT 2001

        UNION ALL

        SELECT 2002
        ) b2
WHERE b.q <> b2.q2
ORDER BY newid()
) b2    
    ORDER BY NEWID()
)
From A

有没有一种优雅的方法来实现这一点而不使用临时/变量表?

抱歉,如果这是一个类似的帖子,但没有使用临时表等找不到任何东西。

sql sql-server random
2个回答
2
投票

尝试以下方法:

declare @tab table ([Date] date, ChannelID int)

insert into @tab
select '01/01/2001', 1001 union
select '02/01/2001', 1001 union
select '03/01/2001', 1001 union
select '04/01/2001', 1001 union
select '05/01/2001', 1001 union
select '06/01/2001', 1001 

select [Date], CASE ascii(newid()) % 3 WHEN 0 THEN '1001' WHEN 1 THEN '2001' ELSE '2002' END AS ChannelID
FROM @tab

加权随机性

drop table if exists #tmp
CREATE TABLE #tmp (rnd_val int, weights int)
INSERT INTO #tmp VALUES (1001, 54);
INSERT INTO #tmp VALUES (2001, 27);
INSERT INTO #tmp VALUES (2002, 21);

update @tab set ChannelID = null

while ((select count(1) from @tab where ChannelID is null) > 0)
begin
    ;with cte as
    (select top 1 [Date], ChannelID from @tab where ChannelID is null)
    update cte set ChannelID = (select top 1 rnd_val from #tmp order by RAND(CAST(NEWID() AS VARBINARY)) * weights desc)
end
select * from @tab

2
投票

你可以做 :

update t 
     set t.ChannelID  = tt.q
from table t cross apply
     ( select top (1) tt.q
       from ( values (1001), (2001), (2002) 
            ) tt (q)
       where cast(tt.q as varchar(255)) <> t.date
       order by newid()
     ) tt;
© www.soinside.com 2019 - 2024. All rights reserved.