The cleanest way I find is to use a view:
create view max_statoatto(
tipo_pratica,
versione,
numero_pratica,
max_prg_atto
) as
select
tipo_pratica,
versione,
numero_pratica,
max(prg_atto) max_prg_atto
from
statoatto
group by
1,2,3
;
SELECT
pr.tipo_pratica,
pr.versione,
pr.numero_pratica,
sa.max_prg_atto,
pr.data_trasmissione,
pr.tipo_atto,
pr.oggetto
FROM
pratica
pr,
max_statoatto sa,
movimenticapitolo mc,
gruppocapitolo gc,
gruppolavoro gl,
gruppoistruttore gi
WHERE
sa.tipo_pratica =
pr.tipo_pratica AND
sa.versione =
pr.versione AND
sa.numero_pratica =
pr.numero_pratica AND
sa.max_prg_atto =
pr.prg_atto and
mc.tipo_pratica = sa.tipo_pratica AND
mc.versione = sa.versione AND
mc.numero_pratica = sa.numero_pratica AND
mc.prg_atto = sa.max_prg_atto and
gc.num_capitolo = mc.numero_capitolo and
gl.id_gruppo = gc.id_gruppo and
gi.id_gruppo = gl.id_gruppo and
gi.cod_fiscale = ? AND
sa.cod_stato = ? AND
year(
pr.data_trasmissione) = ?
understand that you don't create the view everytime, you just create it
once and use for this query. I think I typed it up correctly but just
remember that wherever you used prg_atto use max_prg_atto now. The view
will of course update itself. You can also use your original inner join
syntax if you want I just haven't used it alot so I think in the old
school way. I keep thinking that I will play with the new syntax but I
don't see any great benefit to it except if you like to type "inner
join on" often.