0

SQL Server 2008 R2 を使用すると、クエリによって次の結果セットが返されます -

QID    QcID    QtID    QsID
21      1       SC      3
4       1       SC      1
8       1       MC      1
2       1       SC      1
23      1       SC      3
24      1       SC      3
5       1       SC      1
22      1       SC      3
1       1       SC      1
29      1       MC      3
10      1       MC      1
30      1       MC      3
26      1       MC      3
25      1       SC      3
6       1       MC      1
27      1       MC      3
7       1       MC      1
3       1       SC      1
28      1       MC      3
9       1       MC      1

今、私は 15 の QID のランダムなセットを見つけたいと思っています。

 9 QsID having QsID = 1
 6 QsID having QsID = 3
 9 QtID having QtID = SC
 6 QtID having QtID = MC
 15 QsID having QtID = 1

何万ものレコードがある可能性があるため、パフォーマンスを念頭に置いてどのように実行できるか。

@ Damien_The_Unbeliever 期待される出力は -

21      1       SC       3
4       1       SC       1
8       1       MC       1
2       1       SC       1
23      1       SC       3
24      1       SC       3
5       1       SC       1
1       1       SC       1
10      1       MC       1
25      1       SC       3
6       1       MC       1
27      1       MC       3
7       1       MC       1
3       1       SC       1
28      1       MC       3

また、ランダムを忘れて、すべての条件を満たすセットをどのように選択できるか。

4

2 に答える 2

0

おそらくあなたは試しpercentてみるかもしれませtopん..これは完全な答えではありませんが、方向に光を投げかけるために..

select  * from demo where qid in 
(select top 40 percent qid
 from demo order by newid())
;

こちらも参照先です:http tablesample//msdn.microsoft.com/en-us/library/ms189108.aspx

于 2013-01-24T09:40:43.343 に答える
0

EDIT2:

では、そのためにストアド プロシージャを使用するのはどうでしょうか。
データをサンプリングする条件が 4 セットあると仮定します。あなたが提供した出力から推測されます。正しくないかもしれませんが、好きなように調整できます。

パラメーター:

  • @SIZE- 行単位のサンプリング結果セットのサイズ
  • @P1-@P3- 特定の条件セットに対してランダムな行で埋められるべきサンプリング結果セットの割合。
  • @P4=@SIZE-(@N1+@N2+@N3)
CREATE PROCEDURE sqlsampling 
    @SIZE INT, @P1 DECIMAL(6,4), @P2 DECIMAL(6,4), @P3 DECIMAL(6,4) 
AS 

DECLARE @N1 INT, @N2 INT, @N3 INT, @N4 INT;
SET @N1=CEILING(@SIZE*@P1*0.01);
SET @N2=CEILING(@SIZE*@P2*0.01);
SET @N3=CEILING(@SIZE*@P3*0.01);
SET @N4=@SIZE-(@N1+@N2+@N3);

CREATE TABLE #sample(QID INT, QcID INT, QtID CHAR(2), QsID INT);

INSERT INTO #sample 
SELECT TOP(@N1) * FROM mytable 
WHERE QtID = 'MC' AND QsID = 1 
ORDER BY CHECKSUM(NEWID());

INSERT INTO #sample 
SELECT TOP(@N2) * FROM mytable 
WHERE QtID = 'MC' AND QsID = 3 AND QID NOT IN(SELECT QID FROM #sample)
ORDER BY CHECKSUM(NEWID());

INSERT INTO #sample 
SELECT TOP(@N3) * FROM mytable 
WHERE QtID = 'SC' AND QsID = 1 AND QID NOT IN(SELECT QID FROM #sample)
ORDER BY CHECKSUM(NEWID()); 

INSERT INTO #sample
SELECT TOP(@N4) * FROM mytable 
WHERE QtID = 'SC' AND QsID = 3 AND QID NOT IN(SELECT QID FROM #sample)
ORDER BY CHECKSUM(NEWID());

SELECT * FROM #sample;
DROP TABLE #sample;
GO

このようにサンプルデータで実行すると

EXEC sqlsampling @SIZE=15, @P1=26.666, @P2=13.333, @P3=33.333;

出力が得られます。

QID QCID QTID QSID
10  1    MC   1
9   1    MC   1
7   1    MC   1
6   1    MC   1
27  1    MC   3
30  1    MC   3
1   1    SC   1
4   1    SC   1
3   1    SC   1
5   1    SC   1
2   1    SC   1
21  1    SC   3
23  1    SC   3
25  1    SC   3
24  1    SC   3

その他の考慮事項:

  • 一連の条件の正しいインデックスが役立つはずです
  • CHECKSUM(NEWID())使用のペナルティで少し役立ちますNEWID()

元の答え:

次のようなことができます。

SELECT TOP 15 * FROM
(
SELECT * FROM (SELECT TOP 9 QID FROM mytable 
WHERE QsID = 1 
ORDER BY CHECKSUM(NEWID())) a
 UNION
SELECT * FROM (SELECT TOP 6 QID FROM mytable 
WHERE QsID = 3 
ORDER BY CHECKSUM(NEWID())) b
...
) z ORDER BY CHECKSUM(NEWID())
于 2013-01-24T08:53:11.593 に答える