4

データが関連していない2つのテーブルがありますテーブルAの各行について、テーブルBの3つのランダムな行が必要です

これはカーソルを使用するとかなり簡単ですが、非常に遅いです

では、これを単一のステートメントで表現して RBAR を回避するにはどうすればよいでしょうか?

4

4 に答える 4

3

0 から (N-1) までの乱数を取得するには、次を使用できます。

abs(checksum(newid())) % N

つまり、正の値 1 ~ N を取得するには、次を使用します。

1 + abs(checksum(newid())) % N

注:RAND()機能しません。クエリ バッチごとに 1 回評価され、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 に答える