J'ai le tableau suivant
| id | date | team | |----|------------|------| | 1 | 2019-01-05 | A | | 2 | 2019-01-05 | A | | 3 | 2019-01-01 | A | | 4 | 2019-01-04 | B | | 5 | 2019-01-01 | B |
Comment puis-je interroger le tableau pour recevoir les valeurs les plus récentes pour les équipes?
Par exemple, le résultat ci-dessus table serait des identifiants 1,2,4.
4 Réponses :
Dans ce cas, vous pouvez utiliser les fonctions de fenêtre:
select distinct on (t.team) t.* from t order by t.team, t.date desc;
Dans certaines bases de données une sous-requête corrélée est plus rapide avec les bons index (je ne l'ai pas testé avec Postgres): p >
select t.* from t where t.date = (select max(t2.date) from t t2 where t2.team = t.team);
Et si vous ne vouliez qu'une seule ligne par équipe, la réponse canonique est:
select t.*
from (select t.*, rank() over (partition by team order by date desc) as seqnum
from t
) t
where seqnum = 1;
Cependant, cela ne fonctionne pas dans ce cas, car vous voulez toutes les lignes de la date la plus récente.
Si votre ensemble de données est volumineux, considérez la fonction analytique max dans une sous-requête:
with cte as (
select
id, date, team,
max (date) over (partition by team) as max_date
from t
)
select id
from cte
where date = max_date
Notamment, max est O (n ), il devrait donc être assez efficace. Je ne prétends pas connaître l'implémentation réelle sur PostgreSQL, mais je suppose que c'est O (n).
Encore une possibilité, générique:
select * from t join (select max(date) date,team from t
group by team) tt
using(date,team)
La fonction de fenêtre est la meilleure solution pour vous.
| team | ids | |------|--------| | A | [1, 2] | | B | [4] |
Cette requête renverra cette table:
select team, array_agg(id) ids from ( select team, id, rank() over (partition by team order by date desc) as row_num from table ) t where row_num = 1 group by team
Si vous l'obtenez une ligne par équipe, vous devez utiliser array_agg fonction.
| id | |----| | 1 | | 2 | | 4 |
Cette requête renverra cette table:
select id from ( select team, id, rank() over (partition by team order by date desc) as row_num from table ) t where row_num = 1