Domanda

Prima di tutto, io sono in esecuzione su DB2 per i5 / OS V5R4. Ho ROW_NUMBER (), RANK () e le espressioni di tabella comuni. Faccio non avere TOP n per cento o Limite di offset.

Il set di dati reali con cui sto lavorando è difficile da spiegare, quindi diciamo solo dire che ho un tavolo Storia meteorologica in cui le colonne sono (city, temperature, timestamp). Voglio mettere a confronto le mediane per le medie per ogni (city) gruppo.

Questo è stato il modo più pulito che ho trovato per ottenere un mediano per un'aggregazione tavolo intero. L'ho adattato da IBM Redbook qui :

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

che funziona bene per ottenere una sola fila, ma sembra cadere a pezzi per il raggruppamento. Concettualmente, questo è quello che voglio:


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

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

Ci potrebbe essere una risposta che mi fa sembrare stupido, ma sto avendo un blocco mentale e questo non è il mio # 1 cosa a lavorare in questo momento. Sembra che potrebbe essere possibile, ma non posso usare qualcosa che è estremamente complessa dal momento che è un grande tavolo e voglio la possibilità di personalizzare le colonne vengono aggregate.

È stato utile?

Soluzione

In SQL Server, funzioni come agreagate count (*) può essere partizionato e calcolato, senza un gruppo. Ho guardato rapidamente attraverso il Redbook di riferimento, e sembra che DB2 ha le stesse caratteristiche. Ma se non, allora questo non funzionerà:

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top