2012-02-23 1 views
5

外部企業に何らかのデータを提供する要求がありました。 データのサンプルが必要なのですが、単純なのですか?違う。ここでSQLデータサンプリング

そのサンプリング基準です:720(必要なサンプルサイズ)で割ったレコードの

  • 総数 - これはサンプリング間隔を与える結果が分数である場合(、次の整数に切り捨て数)。

  • サンプリング間隔を半減して開始点を取得します。

  • サンプリング間隔を加算して各レコードを返します。

例:

  • 万レコード - サンプリング間隔= 13(10,000/720)
  • 開始点= 6(13/2四捨五入)
  • 戻りレコード6、19(6+ 13)、32(19 + 13)、45(32 + 13)など.....

誰かがこのようなものは、SQLで可能であるか(あれば)私に言うことができるしてください。

+0

どのブランドのSQLですか?あなたがROW_NUMBER()を持っていれば、それは大いに役立ちます。また、720のサンプリング間隔と定義された開始点***は、データに順序があることを意味します。 - したがって、データはどの順序で表示されるべきですか? – MatBailie

+0

ROW_NUMBER()OVER(TransactionDateで注文)AS RowNumber、 –

答えて

2

ROW_NUMBER()を使用している場合、これは比較的簡単に実行できます。

SELECT 
    * 
FROM 
(
    SELECT 
    ROW_NUMBER() OVER (ORDER BY a, b, c, d) AS record_id, 
    * 
    FROM 
    yourTable 
) 
    AS data 
WHERE 
    (record_id + 360) % 720 = 0 

ROW_NUMBER()(idフィールドの両方で一意であるとのギャップがあってはならないとして、これは重要です)、すべてのデータをシーケンシャル識別子を与えます。また、データの順序を(ORDER BY a, b, c, d)に定義します。

モジュロ(多くの場合、%演算子)を使用すると、レコードが720番目のレコード、1440番目のレコードなどであるかどうかをテストできます(720%720 = 0なので)。

次に、id値を360でオフセットすると、結果セットの開始点を変更できます。

EDIT質問を再読み込みした後

、私はあなたがすべての第720のレコードを望んでいない参照が、一様に720件のレコードを選択しました。このように

(SELECT COUNT(*)/720 FROM yourTable)

720を交換し、正確に720レコードの結果をできるようになります丸め条件を無視(SELECT (COUNT(*)/720)/2 FROM yourTable)

EDIT

360を交換してください。これには、非整数値を使用する必要があり、モジュロの結果は1未満です。

WHERE 
    (record_id + (SELECT COUNT(*) FROM yourTable)/1440.0) 
    % 
    ((SELECT COUNT(*) FROM yourTable)/720.0) 
    < 
    1.0 
+0

OK.So私は収集したデータに対してクエリを実行します。これは9353レコードを返します。サンプリング間隔は12、開始ポイントは6にする必要があります。私はあなたのコードを追加すると、私は779行、任意のアイデアを返しますか? –

+0

@リチャード - 779行は、サンプル間隔を整数に丸めなければならないという要件があるためです。 '9353/720 = 12.99' =>' 12'。そして、 '9353/12 = 779.33' =>' 779'となります。どの部分が最も重要か分かりますか?サンプル間隔を丸めたり、正確に720レコードを返しますか? *** [両方を持つことはできません] *** – MatBailie

+0

データリクエストから、私は720がターゲットであると言います。 –

1
declare @sample_size int, @starting_point int 

select @sample_size = 200 

select top (@sample_size) col1, col2, col3, col4 
from (
    select *, row_number() over (order by col1, col2) as row 
    from your_table 
) t 
where (row % ((select count(*) from your_table)/@sample_size)) - (select count(*) from your_table)/@sample_size/2) = 0 

SQL Serverの2005+で動作するようになるだろう。

TOP (@variable)は、行の数を制限するために使用されます(整数の丸めでは不十分で、必要以上の行が返される可能性があります)。ROW_NUMBER()は行の数と順序を決定します。

の作業例:コードの下http://data.stackexchange.com/stackoverflow/query/62315/sql-data-sampling

declare @tab table (id int identity(1,1), col1 varchar(3), col2 varchar(3)) 

declare @i int 

set @i = 0 

while @i <= 1000 
begin 
    insert into @tab 
    select 'aaa', 'bbb' 
    set @i = @i+1 
end 

declare @sample_size int 

select @sample_size = 123 

select ((select count(*) from @tab)/@sample_size) as sample_interval 

select top (@sample_size) * 
from (
    select *, row_number() over (order by col1, col2, id desc) as row 
    from @tab 
) t 
where (row % ((select count(*) from @tab)/@sample_size)) - ((select count(*) from @tab)/@sample_size/2) = 0 
+0

なぜ "-1"、あなたは説明できますか?多分新しいことを学ぶかもしれない。 –

+0

あなたの解答は良いですが、I -1の理由は動的アプローチではないということです。 SPは実際に開始点自体を計算する必要があります。 –

+0

@リチャード、オクラホマ、誤解を招くことはありませんが、修正して修正するのは簡単です。 –

-1

あなたは、行番号を取得するには、ランクを使用することができます。次のコードは、テーブルに10000のレコードを作成し、合計769行の6番目、19番目、32番目などを選択します。

CREATE TABLE Tbl (
    Data varchar (255) 
) 
GO 

DECLARE @i int 
SET @i = 0 
WHILE (@i < 10000) 
BEGIN 
    INSERT INTO Tbl (Data) VALUES (CONVERT(varchar(255), NEWID())) 
    SET @i = @i + 1 
END 
GO 

DECLARE @interval int 
DECLARE @start int 
DECLARE @total int 
SELECT @total = COUNT(*), 
     @start = FLOOR(COUNT(*)/720)/2, 
     @interval = FLOOR(COUNT(*)/720) 
FROM Tbl 

PRINT 'Start record: ' + CAST(@start as varchar(10)) 
PRINT 'Interval: ' + CAST(@interval as varchar(10)) 

SELECT rank, Data 
FROM (
    SELECT rank() 
    OVER (ORDER BY t.Data) as rank, t.Data AS Data 
    FROM Tbl t) q 
WHERE ((rank + 1) + @start) % @interval = 0 
+0

なぜRANK()ですか?レコードのランキング値が同じ場合、衝突が発生し、同じRANK()で複数の値が発生します。これは、過剰選択(関心のあるRANK()を有する複数の値)とアンダー選択(そのランクに起因するランクが実際に別の位置にあるためにランクがない)の両方につながる可能性がある。 ROW_NUMBER()を使用するだけですか? – MatBailie

0

SQLサーバーには組み込み関数があります。
セレクト姓、名 からPerson.Person TABLESAMPLE(10 PERCENT);