0

まず、DB2 for i5/OS V5R4 を実行しています。ROW_NUMBER()、RANK()、および共通テーブル式があります。TOP n PERCENT または LIMIT OFFSET がありません。

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

これは、テーブル全体の集計の中央値を取得するために見つけた最もクリーンな方法でした。私はここのIBM Redbookからそれを適応させました:

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 ...

都市 | 平均温度 | median_temp       
================================================== =
「ミネアポリス」 | 60 | 64
'ミルウォーキー' | 65 | 66
'マスキーゴン' | 70 | 61

私を愚かに見せる答えがあるかもしれませんが、私はメンタルブロックを抱えており、これは今私が取り組むべき一番のことではありません. 可能だと思われますが、非常に複雑なものは使用できません。これは大きなテーブルであり、集計される列をカスタマイズする機能が必要です。

4

1 に答える 1

1

SQL Server では、count(*) などの集計関数を分割して、group by なしで計算できます。参照されているレッドブックをざっと見てみると、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
于 2009-08-08T00:22:57.010 に答える