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

ORDER BY Sous-requête pour la conversion de GROUP BY en JOIN

Cela peut être simplifié comme suit (le ORDER BY dans la sous-requête ne sert à rien) :

SELECT * 
FROM table
GROUP BY title

Pourquoi pensez-vous que vous avez besoin de JOIN ? (Ok, cela a été résolu par les commentaires).

Après votre commentaire dont vous avez besoin pour chaque titre, la ligne avec le plus grand horodatage, ceci ferait le travail :

SELECT t.* 
FROM
    table AS t
  JOIN
    ( SELECT title
           , MAX(timestamp) AS maxts
      FROM table
      GROUP BY title
    ) AS grp
    ON grp.title = t.title
    AND grp.maxts = t.timestamp
ORDER BY t.timestamp DESC

Pour mémoire, votre requête d'origine :

SELECT * 
FROM 
  ( SELECT * 
    FROM table 
    ORDER BY timestamp DESC 
  ) m
GROUP BY title

pourrait fonctionne comme prévu, mais :seulement dans MySQL qui vous permet d'utiliser dans le SELECT lister les champs qui ne sont pas dans le GROUP BY clause (ou dépendent de celles-ci), sans aucune fonction d'agrégation en eux. Ainsi, la requête ci-dessus renverra un plus ou moins aléatoire ligne pour chaque titre. En fait, il renverra la première ligne qu'il trouvera pour un titre. Donc, après avoir d'abord exécuté la sous-requête (qui s'ordonne par timestamp DESC ) permet de trouver en premier la ligne avec le plus grand horodatage.

Cependant, cela ne se produit que parce que (quand, si) l'optimiseur ne comprend pas que la sous-requête est inutile. Vous constaterez peut-être que votre requête d'origine s'exécute correctement lorsqu'un jour vous effectuez une mise à niveau vers MySQL version 7.5 et que votre requête cesse de fonctionner comme avant. (parce que l'optimiseur est devenu plus intelligent et a traduit votre requête en une requête plus simple sans sous-sélectionner).

Vous pouvez même constater que votre requête cesse complètement de fonctionner et produit une erreur si MySQL décide dans une future version d'être en accord avec les normes SQL pour le GROUP BY requêtes.