4

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

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

那么如何在单个语句中表达这一点以避免 RBAR 呢?

4

4 回答 4

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 行)

于 2012-12-05T16:44:11.607 回答
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
于 2012-12-05T15:49:34.857 回答
0

如果你有一个预先知道的固定数字(比如 3),那么:

select a.*, b.*
from a cross join
     (select top 3 * from b) b

如果你想为“a”中的每一行从“b”随机数行,那么在 SQL Server 中问题会有点困难。

于 2012-12-05T15:55:11.620 回答
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

这是输出的示例

随机行

于 2012-12-05T16:09:41.693 回答