2015-05-29 5 views
6

Рассмотрим эти данные:Обновление таблицы с использованием случайного множества значений в другой таблице

CREATE TABLE #Data (DataID INT, Code VARCHAR(2), Prefix VARCHAR(3)) 

INSERT INTO #Data (DataID, Code) 
VALUES (1, 'AA') 
, (2, 'AA') 
, (3, 'AA') 
, (4, 'AA') 
, (5, 'AA') 
, (6, 'AA') 

CREATE TABLE #Prefix (Code VARCHAR(2), Prefix VARCHAR(3)) 

INSERT INTO #Prefix (Code, Prefix) 
VALUES ('AA', 'ABC') 
, ('AA', 'DEF') 
, ('AA', 'GHI') 
, ('AA', 'JKL') 

Я хочу, чтобы установить значение Prefix в #Data быть случайным Prefix из #Prefix с соответствующим Code.

Использование прямой inner join просто приводит используется одно значение:

UPDATE D 
SET Prefix = P.Prefix 
FROM #Data AS D 
INNER JOIN #Prefix AS P ON D.Code = P.Code 

От читать другие вопросы здесь, NEWID() рекомендуется как способ случайно заказа что-то. Изменение join к:

SELECT TOP 1 subquery ordering by NEWID() 

еще только выбирает одно значение (хотя случайный каждый раз) для каждой строки:

UPDATE D 
SET Prefix = (SELECT TOP 1 P.Prefix FROM #Prefix AS P WHERE P.Code = D.Code ORDER BY NEWID()) 
FROM #Data AS D 

Таким образом, я не уверен, как получить случайный префикс для каждого запись данных из одного оператора обновления. Возможно, я мог бы сделать какую-то петлю через таблицу #Data, но я избегаю никогда не касаться петель в SQL, и я уверен, что это будет медленным. Фактическое применение этого будет на десятках тысяч записей, с сотнями префиксов для десятков кодов.

ответ

8

Вот как это сделать:

UPDATE d SET Prefix = ca.Prefix 
FROM #Data d 
CROSS APPLY(SELECT TOP 1 Prefix 
      FROM #Prefix p 
      WHERE d.DataID = d.DataID AND p.Code = d.Code ORDER BY NEWID()) ca 

Примечание d.DataID = d.DataID. Это необходимо, чтобы заставить двигатель Sql Server пересмотреть подзапрос для каждой строки в таблице #Data.

Смежные вопросы