Замена одного столбца случайно выбранными значениями из другой таблицы

#sql-server #tsql

Вопрос:

Я нашел несколько решений для замены (ниже примера) #test.col2 данными из #test2.src. Но в результате он просто выбирает одно случайное значение и заменяет им их все. Как это исправить? Спасибо!

#тест (целевая таблица)

 col1    col2
-------------
A       1
B       2
C       3
D       4
E       5
 

#тест2 (исходная таблица)

 src1
sample1
sample2
sample3
 

Запрос:

 UPDATE #test
SET col1 = data1.LastName
FROM #test
CROSS APPLY
    (SELECT TOP(1) #test2.LastName
     FROM #test2
     ORDER BY NEWID()) data1
 

Пример результата:

 col1    col2
----------------
A       sample2
B       sample2
C       sample2
D       sample2
E       sample2
 

Ответ №1:

Вот один из способов решить эту проблему. Он использует ROW_NUMBER в cte для «рандомизации» значений.

 if OBJECT_ID('tempdb..#test') is not null
    drop table #test;

create table #test
(
    col1 varchar(20)
    , col2 int
);
insert #test
select 'A', 1 union all
select 'B', 2 union all
select 'C', 3 union all
select 'D', 4 union all
select 'E', 5;

if OBJECT_ID('tempdb..#test2') is not null
    drop table #test2;

create table #test2
(
    LastName varchar(20)
);

insert #test2
select 'src1' union all
select 'sample1' union all
select 'sample2' union all
select 'sample3';

--here is the data before any updates
select * from #test;

with t1 as
(
    select col1
        , col2
        , RowNum = ROW_NUMBER() over(order by newid())
    from #test
)
, t2 as
(
    select LastName
    , RowNum = ROW_NUMBER() over(order by newid())
    from #test2
)

update t
set col1 = t2.LastName
from t1 
join t2 on t1.RowNum = t2.RowNum
join #test t on t.col1 = t1.col1

--we now have updated with a "random" row
select * from #test;
 

Комментарии:

1. Большое спасибо, Шон! Это сработало идеально.. и вы избавили меня от многих часов чесания головы..!