0

0 から N までの値を持つ列 'A' を持つテーブルがあるとします。そして、列 'A' に同じ値を持つ各行を 30% 選択したいと考えています。

So if I have this:
A|  B
-------
0 hello
0 test
0 hi
1 blah1
1 blah2
1 blah3
1 blah4
1 blah5
1 blah6

Result:
A|  B
-------
0 hello
1 blah1
1 blah4

それはblah1またはblah4ではない他の何とかである可能性があり、blah4はblah1ではない他の何とかである可能性があり、基本的にはランダムまたはスキップである可能性があります。

ところで、実際のテーブルは数テラバイトにも及ぶ巨大なものなので、パフォーマンスについて考えてみてください。

4

2 に答える 2

6

このようなことを試してください:

DECLARE @YourTable table (A int, b varchar(10))
INSERT @YourTable VALUES (0, 'hello') --OP's data
INSERT @YourTable VALUES (0, 'test')
INSERT @YourTable VALUES (0, 'hi')
INSERT @YourTable VALUES (1, 'blah1')
INSERT @YourTable VALUES (1, 'blah2')
INSERT @YourTable VALUES (1, 'blah3')
INSERT @YourTable VALUES (1, 'blah4')
INSERT @YourTable VALUES (1, 'blah5')
INSERT @YourTable VALUES (1, 'blah6')

;WITH NumberedRows AS
(   SELECT 
        A,B,ROW_NUMBER() OVER (PARTITION BY A ORDER BY A,B) AS RowNumber
        FROM @YourTable
)
, GroupCounts AS
(   SELECT
        A,MAX(RowNumber) AS MaxA
        FROM NumberedRows
        GROUP BY A
)
SELECT
    n.a,n.b
    FROM NumberedRows           n
        INNER JOIN GroupCounts  c ON n.A=c.A
    WHERE n.RowNUmber<=(c.MaxA+1)*0.3

出力:

a           b
----------- ----------
0           hello
1           blah1
1           blah2

(3 row(s) affected)

Andriy M からのコメントの素晴らしいアイデアに基づいて編集

;WITH NumberedRows AS
(   SELECT 
        A,B,ROW_NUMBER() OVER (PARTITION BY A ORDER BY A,B) AS RowNumber
            ,COUNT(*) OVER (PARTITION BY A) AS TotalOf
        FROM @YourTable
)
SELECT
    n.a,n.b
    FROM NumberedRows            n
    WHERE n.RowNumber<=(n.TotalOf+1)*0.3
    ORDER BY A

出力:

a           b
----------- ----------
0           hello
1           blah1
1           blah2

(3 row(s) affected)

ここでの編集は、Andriy M のアイデアを使用した「ランダムな」行です。

DECLARE @YourTable table (A int, b varchar(10))
INSERT @YourTable VALUES (0, 'hello') --OP's data
INSERT @YourTable VALUES (0, 'test')
INSERT @YourTable VALUES (0, 'hi')
INSERT @YourTable VALUES (1, 'blah1')
INSERT @YourTable VALUES (1, 'blah2')
INSERT @YourTable VALUES (1, 'blah3')
INSERT @YourTable VALUES (1, 'blah4')
INSERT @YourTable VALUES (1, 'blah5')
INSERT @YourTable VALUES (1, 'blah6')

;WITH NumberedRows AS
(   SELECT 
        A,B,ROW_NUMBER() OVER (PARTITION BY A ORDER BY newid()) AS RowNumber
        FROM @YourTable
)
, GroupCounts AS (SELECT A,COUNT(A) AS MaxA FROM NumberedRows GROUP BY A)
SELECT
    n.A,n.B
    FROM NumberedRows           n
        INNER JOIN GroupCounts  c ON n.A=c.A
    WHERE n.RowNUmber<=(c.MaxA+1)*0.3
    ORDER BY n.A

出力:

a           b
----------- ----------
0           hi
1           blah3
1           blah6

(3 row(s) affected)
于 2012-04-30T19:31:04.087 に答える
1

これはサブクエリを 1 つだけ使用するため、セットを 1 回パスします。

SELECT a
    , b
FROM 
    (
        SELECT A
            , b
            , ROW_NUMBER()
                OVER(    PARTITION BY A
                        ORDER BY b
                    ) r
            , COUNT(b)
                OVER(    PARTITION BY A
                    ) ct
        FROM @YourTable
    ) n
WHERE n.r <= n.ct * 0.3

これと同様に、これは常にトップ 3 を返しますが、10 未満であり、「追加」が最初のビンに投稿される場合:

SELECT A
    , b
FROM 
    (
        SELECT A
            , b
            , NTILE(10)
                OVER(   PARTITION BY a
                        ORDER BY b
                    ) tens                          
        FROM @YourTable

    ) n
WHERE tens <= 3;
于 2012-04-30T20:07:29.797 に答える