2012-02-17 66 views
4

以下のSQL ServerのNTILE関数を使用していくつかの結果を四分円に分割しているシナリオがあります。目標は、結果表を以下に示すと4級グループA、B間(9,9,8,8)の分割があるれるSQL Server NTILE - 異なる四分位数の同じ値

case NTILE(4) over (order by t2.TotalStd) 
    when 1 then 'A' when 2 then 'B' when 3 then 'C' else 'D' end as Class 

各クラス内の行として同じ数を有することですCとD

問題を引き起こす2つの結果がありますが、両方の行の合計のstd値は30ですが、異なる四分位数に割り当てられています。

8 30 A 
2 30 B 

同じ値を持つ行が同じ四分位に割り当てられていることを確認する方法はありますか?この現象を起こすために別の列でグループ分けするかパーティション分けすることはできますか?

Pos TotalStd class 
1 16 A 
2 23 A 
3 21 A 
4 29 A 
5 25 A 
6 26 A 
7 28 A 
8 30 A 
9 29 A 
1 31 B 
2 30 B 
3 32 B 
4 32 B 
5 34 B 
6 32 B 
7 34 B 
8 32 B 
9 33 B 
1 36 C 
2 35 C 
3 35 C 
4 35 C 
5 40 C 
6 38 C 
7 41 C 
8 43 C 
1 43 D 
2 48 D 
3 45 D 
4 47 D 
5 44 D 
6 48 D 
7 46 D 
8 57 D 
+1

これはどのように 'である私は、一時テーブル内のカットオフポイントを決定するためにNTILEを使用してそれを行うことができますNTILE'は動作しますが、あなたのベースがすべて同じTotalStdを持っていて四分円をやりたいのであればどうなりますか?とにかく4つの異なるグループに値を分割します – Lamak

答えて

1

ないあなたが本当に、ここで発生するを期待しているものを確認してください。 SQL Serverでは、データを可能な限り同じサイズの4つのグループに分割しています。あなたはにしたいですか?この例を見て:

declare @data table (x int) 

insert @data values 
(1),(2), 
(2),(3), 
(3),(4), 
(4),(5) 

select 
    x, 
    NTILE(4) over (order by x) as ntile 
from @data 

結果:すべての NTILEグループの横に1(S)で値を共有する今

x ntile ----------- ---------- 1 1 2 1 2 2 3 2 3 3 4 3 4 4 5 4 

!しかしそれ以外に何をすべきか?

1

はこれを試してみてください:

; with a as (
         select TotalStd,Class=case ntile(4)over(order by TotalStd) 
                                when 1 then 'A' 
                                when 2 then 'B' 
                                when 3 then 'C' 
                                when 4 then 'D' 
                                end 
                from t2 
                group by TotalStd 
) 
select d.*, a.Class from t2 d 
inner join a on a.TotalStd=d.TotalStd 
order by Class,Pos; 
1

あなたは再ランク機能を使用して、NTILE関数を作成する必要があります。 rank関数は、同じ値を持つ行に対して同じランクを与えます。値は、row_numberを使用したかのように、次のランクに「ジャンプ」します。 この動作を使用してNtile関数を模倣し、同じ値を持つ行に同じNtile値を与えるようにすることができます。しかし、これにより、Ntileパーティションのサイズが変わります。 新しいNTILEは4つのビンを使用するため、以下の例を参照してください。

declare @data table (x int) 

insert @data values 
(1),(2), 
(2),(3), 
(3),(4), 
(4),(5) 

select 
    x, 
    1+(rank() over (order by x)-1) * 4/count(1) over (partition by (select 1)) as new_ntile 
from @data 

結果:

x new_ntile 
--------------- 
1 1 
2 1 
2 1 
3 2 
3 2 
4 3 
4 3 
5 4 
+0

どうしたらいいですか? 'partition by(select 1)'とは何でしょうか? –

+0

"over partition by"句は、 "partition by"列の各値に対して "count(1)"集計を実行します。店舗、曜日、販売日数の3つのフィールドを含む集計された売上テーブルがあるとします。あなたは毎日各店舗の売上シェアを知りたいと思っています。このクエリを使用することができます: "店舗、曜日、売り切れ/売り切れ(売り切れ)を(曜日別にパーティション)"を選択してください。平日がない場合は、パーティションを実行するには、パーティションの列を指定する必要があります。 –

+0

分割の両側で同じ 'partition by'を使用する必要がありますか?つまり、次のようになります。つまり、次のようになります:" select store、sold_amount/sum(sold_amount) '1 +(店舗別パーティション、売上高平日順)-1)* 4/count(1)以上(店舗別パーティション、平日)' –

0

ここでは、34行のテーブルを持っています。

DECLARE @x TABLE (TotalStd INT) 
INSERT @x (TotalStd) VALUES (16), (21), (23), (25), (26), (28), (29), (29), (30), (30), (31), (32), (32), (32), (32), (33), (34), 
    (34), (35), (35), (35), (36), (38), (40), (41), (43), (43), (44), (45), (46), (47), (48), (48), (57) 
SELECT '@x', TotalStd FROM @x ORDER BY TotalStd 

私たちは四分位に分割したい。我々はNTILEを使用する場合は、バケットのサイズはほぼ同じサイズ(8〜9行ごと)になりますが、絆を任意に分割されます。1回分位数1で、一度分位で:

SELECT '@x with NTILE', TotalStd, NTILE(4) OVER (ORDER BY TotalStd) quantile FROM @x 

はが二度表示方法を参照してください。 2.同様に、は私は見つけるべきであること、すなわち完全ではない(分位4分位数3,9で10分位数1の項目、分位数2において8、7位数3,4

の両方に表示され9-8-9-8スプリットですが、私たちがネクタイを任意に破ることが許されない場合、そのような分割は不可能です)。

DECLARE @cutoffs TABLE (quantile INT, min_value INT, max_value INT) 

INSERT @cutoffs (quantile, min_value) 
SELECT y.quantile, MIN(y.TotalStd) 
FROM (SELECT TotalStd, NTILE(4) OVER (ORDER BY TotalStd) AS quantile FROM @x) y 
GROUP BY y.quantile 

-- The max values are the minimum values of the next quintiles 
UPDATE c1 SET c1.max_value = ISNULL(C2.min_value, (SELECT MAX(TotalStd) + 1 FROM @x)) 
FROM @cutoffs c1 LEFT OUTER JOIN @cutoffs c2 ON c2.quantile - 1 = c1.quantile 

SELECT '@cutoffs', * FROM @cutoffs 

我々が最終的なテーブルを作成するために@cutoffsテーブル内の境界値を使用します::

SELECT x.TotalStd, c.quantile FROM @x x 
    INNER JOIN @cutoffs c ON x.TotalStd >= c.min_value AND x.TotalStd < c.max_value 
関連する問題