我有两个数据不相关的表 对于表A中的每一行,我想要例如表B中的3个随机行
使用游标相当容易,但速度非常慢
那么我如何在单一陈述中表达这一点以避免RBAR?
答案 0 :(得分:3)
要获得介于0和(N-1)之间的随机数,您可以使用。
abs(checksum(newid())) % N
这意味着获得正值1-N,您可以使用
1 + abs(checksum(newid())) % N
注意:RAND()
不起作用 - 每个查询批次对其进行一次评估,并且对于tableA的所有行都会遇到相同的值。
查询:
SELECT *
FROM tableA A
JOIN (select *, rn=row_number() over (order by newid())
from tableB) B ON B.rn <= 1 + abs(checksum(newid())) % 9
(假设您希望每A最多9个随机B行)
答案 1 :(得分:0)
假设tableB具有整数代理键,请尝试
Declare @maxRecs integer = 11 -- Maximum number of b records per a record
Select a.*, b.*
From tableA a Join tableB b
On b.PKColumn % (floor(Rand() * @maxRecs)) = 0
答案 2 :(得分:0)
如果你有一个事先知道的固定号码(例如3),那么:
select a.*, b.*
from a cross join
(select top 3 * from b) b
如果你想为“a”中的每一行提供“b”的随机行数,那么SQL Server中的问题就更难了。
答案 3 :(得分:0)
下面是一个如何做到这一点的例子,代码是自包含的,复制并按F5;)
-- create two tables we can join
DECLARE @datatable TABLE(ID INT)
DECLARE @randomtable TABLE(ID INT)
-- add some dummy data
DECLARE @i INT = 1
WHILE(@i < 3) BEGIN
INSERT INTO @datatable (ID) VALUES (@i)
SET @i = @i + 1
END
SET @i = 1
WHILE(@i < 100) BEGIN
INSERT INTO @randomtable (ID) VALUES (@i)
SET @i = @i + 1
END
--The key here being the ORDER BY newid() which makes sure that
--the TOP 3 is different every time
SELECT
d.ID AS DataID
,rtable.ID RandomRow
FROM @datatable d
LEFT JOIN (SELECT TOP 3 * FROM @randomtable ORDER BY newid()) as rtable ON 1 = 1
下面是输出的一个例子