117 votes

Obtenir la ligne la plus récente pour un ID donné

Dans le tableau ci-dessous, comment puis-je obtenir seulement le la ligne la plus récente con id=1 sur la base de la signin et non les 3 lignes ?

+----+---------------------+---------+
| id | signin              | signout |
+----+---------------------+---------+
|  1 | 2011-12-12 09:27:24 | NULL    |
|  1 | 2011-12-13 09:27:31 | NULL    |
|  1 | 2011-12-14 09:27:34 | NULL    |
|  2 | 2011-12-14 09:28:21 | NULL    |
+----+---------------------+---------+

135voto

Michael Berkowski Points 137903

Utilisez l'agrégat MAX(signin) groupés par id. Cela permettra de lister les plus récents signin pour chaque id .

SELECT 
 id, 
 MAX(signin) AS most_recent_signin
FROM tbl
GROUP BY id

Pour obtenir l'ensemble de l'enregistrement unique, effectuez un INNER JOIN par rapport à une sous-requête qui renvoie uniquement le MAX(signin) par id.

SELECT 
  tbl.id,
  signin,
  signout
FROM tbl
  INNER JOIN (
    SELECT id, MAX(signin) AS maxsign FROM tbl GROUP BY id
  ) ms ON tbl.id = ms.id AND signin = maxsign
WHERE tbl.id=1

0 votes

Voici ce qui a marché en fonction de votre premièrement réponse : SELECT id, MAX(signin) FROM tbl GROUP BY id WHERE id=1;

0 votes

J'ai essayé de mettre en œuvre la deuxième solution (pour obtenir la ligne entière) dans ma propre situation, mais j'obtiens toujours un ensemble de résultats vide.

0 votes

La réponse de @rantsh xQbert avait la version correcte de ce que j'avais initialement ci-dessus, mais je préfère la solution que je viens de changer.

99voto

Erwin Brandstetter Points 110228
SELECT *
FROM   tbl
WHERE  id = 1
ORDER  BY signin DESC
LIMIT  1;

L'indice évident serait sur (id) ou un indice multicolonne en (id, signin DESC) .

De manière pratique pour le cas présent, MySQL trie NULL valeurs dernier dans l'ordre décroissant. C'est ce que vous voulez généralement s'il peut y avoir NULL Valeurs : la ligne avec la dernière valeur non nulle. signin .

Pour obtenir NULL en premier lieu :

ORDER BY signin IS NOT NULL, signin DESC

Vous pouvez ajouter d'autres expressions à ORDER BY pour obtenir un choix déterministe à partir de (potentiellement) plusieurs rangées avec NULL .
Il en va de même sans NULL si signin n'est pas défini UNIQUE .

En rapport :

La norme SQL ne définit pas explicitement un ordre de tri par défaut pour les fichiers NULL valeurs. Le comportement varie beaucoup d'un SGBDR à l'autre. Voir :

Mais il y a son le site NULLS FIRST / NULLS LAST définies dans le standard SQL et supportées par la plupart des principaux SGBD, mais pas par MySQL. Voir :

10voto

rantsh Points 356

En vous basant sur les réponses de @xQbert, vous pouvez éviter la sous-requête et la rendre suffisamment générique pour filtrer par n'importe quel ID.

SELECT id, signin, signout
FROM dTable
INNER JOIN(
  SELECT id, MAX(signin) AS signin
  FROM dTable
  GROUP BY id
) AS t1 USING(id, signin)

1 votes

Bonjour, comment fonctionne cette requête et est-elle plus efficace que la réponse de xQbert ? Les deux requêtes s'exécutent à peu près en même temps pour moi et je ne comprends pas la partie utilisation de la requête qui remplace ce qui est habituellement et sur.

4voto

xQbert Points 10091
Select [insert your fields here]
from tablename 
where signin = (select max(signin) from tablename where ID = 1)

1voto

Ales Points 187

J'ai eu un problème similaire. J'avais besoin d'obtenir la dernière version de la traduction du contenu de la page, en d'autres termes, d'obtenir l'enregistrement spécifique qui a le numéro le plus élevé dans la colonne version. Je sélectionne donc tous les enregistrements classés par version, puis je prends la première ligne du résultat (en utilisant la clause LIMIT).

SELECT *
FROM `page_contents_translations`
ORDER BY version DESC
LIMIT 1

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X