質問

まず第一に、私は、i5 / OS V5R4用DB2上で実行しています。私はROW_NUMBER()、RANK()と共通テーブル式を持っています。私がやるの TOP N PERCENTまたはLIMITがOFFSETていない。

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

これは私がテーブル全体の集約のための中央値を取得することが分かっクリーンな方法でした。

:私は、IBMレッドブックここのからそれを適応しました
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

その背中単一の行を取得するために適していますが、グループ化にバラバラのようです。概念的には、これは私が欲しいものです。


SELECT city, AVG(temperature), MEDIAN(temperature) FROM ...

city           | mean_temp       | median_temp       
===================================================
'Minneapolis'  | 60              | 64
'Milwaukee'    | 65              | 66
'Muskegon'     | 70              | 61

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

役に立ちましたか?

解決

SQL Serverでは、COUNT(*)のようなagreagate機能がでグループなしで分割して計算することができます。私は、参照レッドブックをすばやく見て、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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top