2009-08-07 12 views
0

まず、DB2 for i5/OS V5R4を実行しています。私はROW_NUMBER()、RANK()、共通テーブル式を持っています。私はではなく、にはTOP n PERCENTまたはLIMIT OFFSETがあります。DB2 SQL - GROUP BYの中央値

私が扱っている実際のデータセットは説明するのが難しいので、列が(city, temperature, timestamp)の気象履歴表があるとしましょう。私は各グループの平均値を中央値と比較したいと思っています(city)

これは、全体のテーブル集計の中央値を取得するのが最もクリーンな方法でした。バック単一の行を取得するためにうまく機能

WITH base_t AS 
(SELECT temp, row_number() over (order by temperature) AS rownum FROM t), 
count_t AS 
(SELECT COUNT(temperature) + 1 AS base_count FROM base_t), 
median_t AS 
(SELECT temperature FROM base_t, count_t 
    WHERE rownum in (FLOOR(base_count/2e0), CEILING(base_count/2e0))) 
SELECT DECIMAL(AVG(temperature),10,2) AS median FROM median_t 

を、グループ化にバラバラのようです:私は、IBMレッドブックhereからそれを適応しました。概念的には、これは私が欲しいものです:


SELECT city, AVG(temperature), MEDIAN(temperature) FROM ... 
 
city   | mean_temp  | median_temp  
=================================================== 
'Minneapolis' | 60    | 64 
'Milwaukee' | 65    | 66 
'Muskegon'  | 70    | 61 

私は愚かに見えるのですが、私は精神的なブロックを持つことだし、これが今の仕事に私の#1の事ではないの答えがあるかもしれません。それは可能かもしれないようですが、大きなテーブルなので非常に複雑なものを使用することはできません。どの列を集約するかをカスタマイズする必要があります。

答えて

1

SQL Serverでは、count(*)などの機能はグループ化せずにグループ化することができます。私は参照されたredbookをすばやく見て、DB2と同じ機能があるように見えます。しかし、そうでない場合、これはうまくいかないでしょう:

create table TemperatureHistory 
    (City varchar(20) 
    , Temperature decimal(5, 2) 
    , DateTaken datetime) 

insert into TemperatureHistory values ('Minneapolis', 61, '20090101') 
insert into TemperatureHistory values ('Minneapolis', 59, '20090102') 

insert into TemperatureHistory values ('Milwaukee', 65, '20090101') 
insert into TemperatureHistory values ('Milwaukee', 65, '20090102') 
insert into TemperatureHistory values ('Milwaukee', 100, '20090103') 

insert into TemperatureHistory values ('Muskegon', 80, '20090101') 
insert into TemperatureHistory values ('Muskegon', 70, '20090102') 
insert into TemperatureHistory values ('Muskegon', 70, '20090103') 
insert into TemperatureHistory values ('Muskegon', 20, '20090104') 

; with base_t as 
    (select city 
     , Temperature 
     , row_number() over (partition by city order by temperature) as RowNum 
     , (count(*) over (partition by city)) + 1 as CountPlusOne 
    from TemperatureHistory) 
select City 
    , avg(Temperature) as MeanTemp 
    , avg(case 
     when RowNum in (FLOOR(CountPlusOne/2.0), CEILING(CountPlusOne/2.0)) 
      then Temperature 
      else null end) as MedianTemp 
from base_t 
group by City 
+0

私はこれを試してみます。私は本当にOLAPをよく理解する必要があります。ありがとう。 – twblamer

+0

私はこれを受け入れられる回答として設定しています。それはDB2 LUW 9.5のカウント(*)で動作しますが、残念ながら、DB2 for iでは動作しません。誰も他のアイデアを持っていないので、私はこの制限で生きなければならないと思う。再度、感謝します。 – twblamer