我有两个单列表,A和B.我想创建一个新表,其中A的每个元素与来自B的3个随机元素的样本配对,即:
表A:
A1
A2
A3
表B:
B1
B2
B3
...
B100
结果表C:
A1 B51
A1 B63
A1 B17
A2 B62
A2 B13
A2 B17
A3 B1
A3 B69
A3 B78
对于每个A,B的值是随机的。重复/重叠对于不同的As是好的,但对于给定的A不是(即每个A必须与B的3个唯一元素配对,但是不同的As可以具有相同的元素来自B;也就是说,不同的As应该极不可能有相同的B组)。有没有办法在没有对A?
的元素使用for循环的情况下执行此操作答案 0 :(得分:3)
我认为最简单的方法可能是outer apply
:
select a.*, b.*
from a outer apply
(select top 3 b.*
from b
where b.id <> a.id -- just needed to prevent correlation "optimization"
order by newid()
) b;
我强调“简单”。对于较大的b
表,Ross的解决方案可能更快。
答案 1 :(得分:0)
这样做会但是速度不是很快。假设F1是A的主键(或者至少是A的一些唯一键),F2是你想要的B值(主键或不是主键):
WITH X AS (
SELECT A.F1, ROW_NUMBER() OVER (ORDER BY A.F1) AS N
FROM A
), Y AS (
SELECT B.F2, ROW_NUMBER() OVER (ORDER BY NEWID()) AS N
FROM B
)
SELECT A.F1, B.F2
FROM X INNER JOIN Y ON Y.N BETWEEN (X.N-1)*10+1 and ((X.N)*10)
编辑:修复一个错误。现在使用Y.N = 1..10表示X.N = 1,Y.N = 11..20表示X.N = 2,等等。
答案 2 :(得分:0)
我相信这有效:
;
WITH RandomBs
AS ( SELECT c.ClientId AS val
, ROW_NUMBER() OVER ( ORDER BY ( SELECT NEWID() ) ) rn
FROM Clients c),
A AS ( SELECT DO.OrganizationId
, ROW_NUMBER() OVER ( ORDER BY ( SELECT NULL ) ) rn
FROM Organizations DO)
SELECT *
FROM A
CROSS APPLY ( SELECT val
FROM RandomBs
WHERE rn BETWEEN ( ( ( A.rn - 1 ) * 10 ) + 1 ) AND ( (A.rn * 10) ) ) x