Заменить существующие значения в таблице новыми значениями из списка в случайном порядке. - PullRequest
0 голосов
/ 05 сентября 2018

Простой стол

    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

Мне нужно заменить значения ChannelID на 1001, 2001 или 2002, случайно в каждой строке.

Я попытался сделать следующее, но, похоже, не дал мне случайных записей, и почему-то пропустил последнее значение.

    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

Есть ли элегантный способ достичь этого без использования временных / переменных таблиц?

Извините, если это аналогичный пост, но не смог найти ничего без использования временных таблиц и т. Д.

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

попробуйте следующее:

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
0 голосов
/ 05 сентября 2018

Вы можете сделать:

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;
...