2013-02-25 6 views
3

У меня есть таблица MyTable, которая имеет поле внешнего ключа OtherTableID.Как рандомизировать значение внешнего ключа в SQL?

У меня уже есть несколько тысяч строк в MyTable. Теперь я хочу рандомизировать OtherTableID так, чтобы у него было какое-то случайное (но действительное) значение записи в OtherTable.

Любые идеи, как это сделать в одном аккуратном запросе, не используя курсор?

+0

У вас есть обновление каскада? –

+0

@ Тони Хопкинсон - Я могу это сделать, если это поможет. Что у тебя на уме? –

+0

Какие данные хранятся в столбце OtherTableID, целые числа? – Byron

ответ

8
;WITH x AS 
(
    /* apply a random row number to the other table */ 
    SELECT ID, rn = ROW_NUMBER() OVER (ORDER BY NEWID()) 
    FROM dbo.OtherTable 
), 
y AS 
(
    /* apply a sequential row number to the source table */ 
    SELECT ID, OtherTableID, rn = ROW_NUMBER() OVER (ORDER BY ID) 
    FROM dbo.MyTable 
) 
/* now perform an update using a join on those row numbers */ 
UPDATE y SET OtherTableID = x.ID 
    FROM y INNER JOIN x 
    ON y.rn = x.rn; 

Это не должно производить дубликаты, пока dbo.OtherTable.ID уникален. Также это зависит от того, что вы сказали - в строке dbo.OtherTable больше строк.

+0

Почему у него точка с запятой перед 'WITH'? –

+1

@Shaul, потому что для завершения утверждения, предшествующего 'WITH', требуется полутолщина. Поскольку [большинство людей все еще этого не делают, даже если они должны] (http://sqlblog.com/blogs/aaron_bertrand/archive/2012/12/21/16567.aspx), если они копируют и вставляют мой код, они жалуются, что он ломается (когда действительно проблема в том, что у них отсутствовала точка с запятой). Поэтому я включаю его. Ничего не повредит - 'SELECT 1 ;;;;;;;;;;;;;; SELECT 2;' является действительным T-SQL. –

+0

Прохладный, спасибо за ссылку, что точки с запятой становятся обязательными - я понятия не имел! –

0

Редактировать 5: После тестирования эта работа похожа на очарование, если вы не заботитесь о дублировании. 100% случайный. Вы можете настроить его, чтобы не допускать дублирования.

;WITH X AS 
(
SELECT ROW_NUMBER() OVER(ORDER BY IdOtherTable) AS 'Row', IdOtherTable 
    FROM OtherTable 
) 




UPDATE MyTable 
SET  IdOtherTable = (SELECT IdOtherTable 
      FROM X 
      WHERE Row = round((SELECT RAND() * (SELECT COUNT(IdOtherTable) 
               FROM  OtherTable)), 0, 1) + 1) 
Смежные вопросы