mercoledì 20 gennaio 2016

Sql per estrarre un valore massimo tra quelli presenti in un gruppo

Ieri mi sono scervellato per arrivare ad ottenere l’estrazione del valore massimo tra quelli presenti in una tabella Postgres. In pratica data una tabella A, per alcune righe che non hanno valorizzata una determinata colonna c, voglio trovare data una chiave di 3 valori che in questo caso saranno blocco, loco e data uscita, i valori di una colonna c, data ingresso massima relativi a righe diverse. Come spesso succede in questi casi un esempio vale più di mille parole.
Data la query:

select distinct b.blocco, b.loco, b.data_ora_uscita_programmata, b.data_ora_ingresso_effettiva, c.data_ora_ingresso_effettiva
from matr_dati b, matr_dati c
where
b.blocco = c.blocco and b.loco = c.loco and
c.data_ora_ingresso_effettiva is not null and
c.data_ora_ingresso_effettiva < b.data_ora_uscita_programmata and
b.data_ora_uscita_programmata >= to_date('15102015','ddMMyyyy') and
b.data_ora_uscita_programmata < to_date('22102015','ddMMyyyy') and
b.data_ora_ingresso_effettiva is null  and
b.blocco in ('LM14PXC329','LM10MDT144','LM10MDT143')
order by b.blocco,b.loco, b.data_ora_uscita_programmata asc

ottengo questi valori:
blocco                loco            uscita                        ingresso_a       ingresso_b
LM10MDT143    E464194    2015-10-18 12:22:00    (null)    2015-10-15 15:20:17
LM10MDT143    E464194    2015-10-18 12:22:00    (null)    2015-10-16 09:32:52
LM10MDT143    E464194    2015-10-18 12:22:00    (null)    2015-10-17 15:18:09
LM10MDT143    E464194    2015-10-20 12:22:00    (null)    2015-10-15 15:20:17
LM10MDT143    E464194    2015-10-20 12:22:00    (null)    2015-10-16 09:32:52
LM10MDT143    E464194    2015-10-20 12:22:00    (null)    2015-10-17 15:18:09
LM10MDT143    E464194    2015-10-20 12:22:00    (null)    2015-10-19 15:13:08
LM10MDT144    E464191    2015-10-17 12:22:00    (null)    2015-10-15 09:44:46
LM10MDT144    E464191    2015-10-19 12:22:00    (null)    2015-10-15 09:44:46
LM10MDT144    E464191    2015-10-20 17:04:00    (null)    2015-10-15 09:44:46
LM14PXC329    E464197    2015-10-19 17:31:00    (null)    2015-10-16 11:01:20
LM14PXC329    E464197    2015-10-21 17:31:00    (null)    2015-10-16 11:01:20
Come si vede ad ogni tripletta blocco,loco, ingresso corrispondono più uscite. Per associare ad ogni tripletta blocco,loco, data uscita la data di valore ingresso_b massima modifico la query precedente usando un inner_join nel seguente modo:
select distinct b.blocco, b.loco, b.data_ora_uscita_programmata as uscita, b.data_ora_ingresso_effettiva as ingresso_a, c.data_ora_ingresso_effettiva as ingresso_b
from matr_dati b, matr_dati c inner join (
select c.blocco as blocco, c.loco as loco, max(c.data_ora_ingresso_effettiva) as MaxDataOraIngressoEffettiva from matr_dati c
where c.data_ora_ingresso_effettiva < to_date('22102015','ddMMyyyy')
group by c.blocco, c.loco
) MaxIngresso on (c.loco=MaxIngresso.loco and c.blocco=MaxIngresso.blocco and c.data_ora_ingresso_effettiva = MaxIngresso.MaxDataOraIngressoEffettiva )
where
b.blocco = c.blocco and b.loco = c.loco and
c.data_ora_ingresso_effettiva is not null and
c.data_ora_ingresso_effettiva < b.data_ora_uscita_programmata and b.data_ora_uscita_programmata >= to_date('15102015','ddMMyyyy') and
b.data_ora_uscita_programmata < to_date('22102015','ddMMyyyy') and
b.data_ora_ingresso_effettiva is null and
b.blocco in ('LM14PXC329','LM10MDT144','LM10MDT143')
order by b.blocco,b.loco, b.data_ora_uscita_programmata asc

ottenendo quindi il risultato riportato:
blocco               loco               uscita                 ingresso_a    ingresso_b
LM10MDT143    E464194    2015-10-20 12:22:00    (null)    2015-10-19 15:13:08
LM10MDT144    E464191    2015-10-17 12:22:00    (null)    2015-10-15 09:44:46
LM10MDT144    E464191    2015-10-19 12:22:00    (null)    2015-10-15 09:44:46
LM10MDT144    E464191    2015-10-20 17:04:00    (null)    2015-10-15 09:44:46
LM14PXC329    E464197    2015-10-19 17:31:00    (null)    2015-10-16 11:01:20
LM14PXC329    E464197    2015-10-21 17:31:00    (null)    2015-10-16 11:01:20
In questo modo ad ogni tripletta blocco,loco,data uscita ho associato la data di ingresso_b relativa al valore massimo.

Nessun commento:

Posta un commento