PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

PostgreSQL, agrégat personnalisé

Vous avez dit dans les commentaires qu'un code peut avoir deux lignes avec la même date. Ce sont donc des données sensées.

01.01.2014  1   3.50
01.01.2014  1  17.25
01.01.2014  1  99.34

Il n'y a aucun moyen déterministe de dire laquelle de ces lignes est la "dernière", même si vous triez par code et "date". (Dans le modèle relationnel - un modèle basé sur des ensembles mathématiques - l'ordre des colonnes n'est pas pertinent, et l'ordre des lignes n'est pas pertinent.) L'optimiseur de requête est libre de renvoyer les lignes comme il le pense le mieux, donc cette requête

select *
from temp1
order by mydate, code

pourrait renvoyer ceci en une seule fois,

01.01.2014  1   3.50
01.01.2014  1  17.25
01.01.2014  1  99.34

et ceci sur un autre.

01.01.2014  1   3.50
01.01.2014  1  99.34
01.01.2014  1  17.25

Sauf si vous stockez une valeur qui rend le sens de dernier évident, ce que vous essayez de faire n'est pas possible. Quand les gens ont besoin de faire dernière évident, ils utilisent généralement un horodatage.

Après vos modifications, cette requête semble renvoyer ce que vous recherchez.

with distinct_codes as (
  select distinct code 
  from temp1
),
corrected_table as (
select 
  case when mydate <> '' then TO_TIMESTAMP(mydate, 'DD.MM.YYYY HH24:MI:SS')
       else null
  end as mydate, 
  code, 
  price
from temp1
),
max_dates as (
  select code, max(mydate) max_date
  from corrected_table
  group by code
)
select c1.mydate, d1.code, coalesce(c1.price, 0)
from corrected_table c1
inner join max_dates m1
        on m1.code = c1.code
       and m1.max_date = c1.mydate
right join distinct_codes d1
        on d1.code = c1.code
order by code;