2017-06-23 42 views
0

樣品的%I有如下的數據集:分區通過PL SQL(Oracle)的

Ranking Segment Month 
1 1 201501 
2 1 201501 
3 1 201501 
4 1 201501 
5 1 201501 
6 1 201501 
7 1 201501 
… 1 201501 
567 1 201501 
1 2 201501 
2 2 201501 
3 2 201501 
4 2 201501 
….. 2 201501 
456 2 201501 
1 1 201502 
2 1 201502 
3 1 201502 
4 1 201502 
5 1 201502 
6 1 201502 
7 1 201502 
… 1 201502 
326 1 201502 
1 2 201502 
2 2 201502 
3 2 201502 
4 2 201502 
… 2 201502 
562 2 201502 
........... 

我需要每一個數據段分割成包含它的5%的基團。由於每個細分市場每個月都有不同的銷售數量,您能否告訴我如何將每個細分市場按照排名分成20個包含5%訂單的小組?

謝謝!

回答

0

一種方法是使用count(*)作爲窗口函數。目前還不清楚每個組需要哪種類型的樣本。

下做了第一個「n」的樣本,假設ranking沒有間隙或重複:

select t.*, 
     floor(20 * (ranking - 1)/cnt) as grp 
from (select t.*, count(*) over (partition by segment, month) as cnt 
     from t 
    ) t; 

如果有間隙或重複的,你可以使用row_number()得到正確的枚舉。

0

根據您的輸入數據,您不會說出您的預期輸出是什麼。也許ntile()是你所追求的,例如:

WITH sample_data AS (SELECT LEVEL ranking, 1 SEGMENT, 201501 mnth FROM dual CONNECT BY LEVEL <= 21 UNION ALL 
        SELECT LEVEL ranking, 2 SEGMENT, 201501 mnth FROM dual CONNECT BY LEVEL <= 40 UNION ALL 
        SELECT LEVEL ranking, 1 SEGMENT, 201502 mnth FROM dual CONNECT BY LEVEL <= 60 UNION ALL 
        SELECT LEVEL ranking, 2 SEGMENT, 201502 mnth FROM dual CONNECT BY LEVEL <= 80) 
SELECT ranking, 
     segment, 
     mnth, 
     NTILE(20) OVER (PARTITION BY mnth, SEGMENT ORDER BY ranking) grp 
FROM sample_data; 

    RANKING SEGMENT  MNTH  GRP 
---------- ---------- ---------- ---------- 
     1   1  201501   1 
     2   1  201501   1 
     3   1  201501   2 
     4   1  201501   3 
     ... 
     19   1  201501   18 
     20   1  201501   19 
     21   1  201501   20 
     1   2  201501   1 
     2   2  201501   1 
     3   2  201501   2 
     4   2  201501   2 
     5   2  201501   3 
     ... 
     36   2  201501   18 
     37   2  201501   19 
     38   2  201501   19 
     39   2  201501   20 
     40   2  201501   20 
     1   1  201502   1 
     2   1  201502   1 
     3   1  201502   1 
     4   1  201502   2 
     5   1  201502   2 
     6   1  201502   2 
     7   1  201502   3 
     ... 
     54   1  201502   18 
     55   1  201502   19 
     56   1  201502   19 
     57   1  201502   19 
     58   1  201502   20 
     59   1  201502   20 
     60   1  201502   20 
     1   2  201502   1 
     2   2  201502   1 
     3   2  201502   1 
     4   2  201502   1 
     5   2  201502   2 
     6   2  201502   2 
     7   2  201502   2 
     8   2  201502   2 
     9   2  201502   3 
     ... 
     72   2  201502   18 
     73   2  201502   19 
     74   2  201502   19 
     75   2  201502   19 
     76   2  201502   19 
     77   2  201502   20 
     78   2  201502   20 
     79   2  201502   20 
     80   2  201502   20 

N.B.首先填滿先前的桶,例如對於我上面的例子中的段1和月201501,grp = 1有2行,而所有其他行有1行。如果你想要它,以便後面的桶充滿更多,你可以簡單地顛倒ntile ,然後減去從桶+ 1的數,所以你的情況,這將是:

21 - NTILE(20) OVER (PARTITION BY mnth, SEGMENT ORDER BY ranking DESC) 
0

您正在尋找NTILE(20)其將在每個5%塊中的數據。

select ranking, segment, month 
from 
(
    select 
    ranking, segment, month, 
    ntile(20) over (partition by segment, month order by ranking) as tile 
    from mytable 
) 
where tile = 1 
order by month, segment, ranking;