SQL:如何从一个表中为另一个表中的每一行获取随机行数

时间:2012-12-05 15:41:19

标签: sql sql-server-2008 random

我有两个数据不相关的表 对于表A中的每一行,我想要例如表B中的3个随机行

使用游标相当容易,但速度非常慢

那么我如何在单一陈述中表达这一点以避免RBAR?

4 个答案:

答案 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

下面是输出的一个例子

randomrow