使用其他表中的多个值的随机更新表

Joh*_*aka 7 sql t-sql sql-server random sql-server-2012

考虑这些数据:

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')
Run Code Online (Sandbox Code Playgroud)

我想设置的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
Run Code Online (Sandbox Code Playgroud)

从这里阅读其他问题,NEWID()建议作为随机排序的方式.更改join到:

SELECT TOP 1 subquery ordering by NEWID() 
Run Code Online (Sandbox Code Playgroud)

仍然只为每一行选择一个值(每次随机):

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
Run Code Online (Sandbox Code Playgroud)

所以,我不确定如何从单个更新语句中为每个数据条目获取随机前缀.我可能会在#Data桌子上做一些循环,但我避免接触循环SQL,我相信这会很慢.这个实际应用将在成千上万的记录中,有数百个代码的数百个前缀.

Gio*_*uri 10

这是怎么做的:

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
Run Code Online (Sandbox Code Playgroud)

注意事项d.DataID = d.DataID.这是为了强制Sql Server引擎重新评估#Data表中每行的子查询.