Disons que j'ai ce tableau
SELECT DISTINCT name, val FROM answer AS sf LEFT JOIN user AS u ON u.id_user = sf.id_user WHERE sf.id_feedback = 1 ORDER BY name
Je veux obtenir la dernière réponse pour chaque utilisateur (MAX (année) et MAX (mois))
name | val -----+----- user1| YES user2| YES user3| NO
3 Réponses :
Premier groupe pour obtenir les dates maximales de chaque utilisateur, puis rejoignez:
select a.name, a.val from answer as a inner join ( select name, max(year & month) as maxdate from answer group by name ) as g on g.name = a.name and g.maxdate = (a.year & a.month)
Si les colonnes year
et month
sont du texte puis:
select a.name, a.val from answer as a inner join ( select name, max(dateserial(year, month, 1)) as maxdate from answer group by name ) as g on g.name = a.name and g.maxdate = dateserial(a.year, a.month, 1)
Vous pouvez utiliser une sous-requête corrélée:
select t.name, t.val from table t where t.pk = (select top 1 t1.pk from table t1 where t1.name = t.name order by t1.year desc, t1.month desc );
pk
indique la colonne d'identité qui identifie l'ordre des colonnes.
vous supposez qu'une colonne pk existe ici. Il n'y a rien dans la question sur pk.
Voici une autre méthode, utilisant une sous-requête corrélée:
select a.name, a.val from answer a where not exists (select 1 from answer b where a.name = b.name and dateserial(a.year,a.month,1) < dateserial(b.year,b.month,1))
MODIFIER: Code corrigé ci-dessous pour tenir compte des cas où les champs de l'année correspondent, mais les champs du mois diffèrent : (merci @ Scorpioo590)
select a.name, a.val from answer a where not exists (select 1 from answer b where a.name = b.name and (a.year < b.year or (a.year = b.year and a.month < b.month)))
Alternativement, en utilisant dateserial
:
select a.name, a.val from answer a where not exists (select 1 from answer b where a.name = b.name and a.year < b.year and a.month < b.month)
Cela ne fonctionnera que si l'année et le mois de l'entrée souhaitée sont plus grands que toutes les autres valeurs. Supposons que vous ayez deux lignes 2019-01 et 2019-02. Puisqu'il n'existe pas d'entrée où l'année est la plus grande, les deux entrées seraient sélectionnées
WHERE a.name = b.name AND (a.year
@ Scorpioo590 Merci beaucoup, j'avais oublié ce cas - j'ai mis à jour ma réponse ci-dessus. Merci d'avoir attiré mon attention là-dessus.
Les champs
année
etmois
sont-ils numériques? Ces données sont-elles vraiment stockées dans une seule table? Comme votre exemple de requête l'indique autrement.