2016-04-05 14 views
0

アカウント番号で人口の割合を選択しようとしていますが、その割合を部門別に均等に配分する必要があります。例えばアカウント単位でN個の割合を選択してください

私は、部門別の内訳は10%が必要なアカウント12345のための100行を持っています。

dept count 
1  2 
2  2 
3  2 
4  2 
5  2 

パーセントはいつでも変更できます。誰も私のための良いアイディアを持っていますか?私はtablesample関数を使用しようとしましたが、それは私が達成しようとしているもののために限られていたようです。

+0

あなたは、各部門の10%、または部門で均等に分割全人口の10%が必要ですか?また、ランダムサンプルが必要ですか? – Kateract

答えて

2

十分な行があると仮定して、ウィンドウ関数を使用できます。このトリックで均等に配信された10%のサンプルを取得するには:

select t.* 
from (select t.*, row_number() over (partition by account order by seqnum_within_account) as seqnum 
     from (select t.*, 
        row_number() over (partition by account, dept order by (select null)) as seqnum_within_account, 
        count(*) over (partition by account) as cnt 
      from t 
      ) t 
    ) t 
where seqnum * 10 <= cnt; 

これは何をしていますか?最も内側のselectは、各アカウント内の各部門に順次番号を割り当てます。次に、各アカウント内でシーケンス番号を割り当てるため、部門間で均等に分散されます。したがって、n個の部門がある場合、最初のn個の値は異なる部門からのものであり、次のn個など(十分な行があると仮定して)です。

最後のwhereは10%のサンプルを取ります。

注:1つのアカウントの情報のみを必要とする場合は、最も内側のサブクエリにwhere account = ???を追加できます。

+0

私は、アカウントごとにシーケンス番号を生成するには、seqnum_within_account –

+0

@ConsiderMeで注文する必要があると思います。 。 。ありがとうございました。 –

0

利用ROW_NUMBER()窓関数

;with cte as (
    select * 
    , ROW_NUMBER() over (partition by dept order by AccountNo) AS Rn 
    , count(AccountNo) over (partition by dept order by dept) AS Cnt 
    from #tt 
) 
select * 
from cte 
where Rn<=(1.0*Cnt)/10 
関連する問題