49 votes

Ordre MySQL avant le groupe par

Je dois trouver le dernier message pour chaque auteur, puis regrouper les résultats afin que je ne dispose que d'un seul dernier message pour chaque auteur.

 SELECT wp_posts.* FROM wp_posts
        WHERE wp_posts.post_status='publish'
        AND wp_posts.post_type='post'
        GROUP BY wp_posts.post_author           
        ORDER BY wp_posts.post_date DESC
 

Ceci regroupe correctement la sortie, de sorte que je ne reçois qu'un seul article par auteur, mais il ordonne les résultats une fois qu'ils ont été groupés et non avant leur sélection.

22voto

edze Points 2004
SELECT
    wp_posts.*
FROM wp_posts
WHERE
    wp_posts.post_status='publish'
    AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author
HAVING wp_posts.post_date = MAX(wp_posts.post_date) <- ONLY THE LAST POST FOR EACH AUTHOR
ORDER BY wp_posts.post_date DESC

EDIT:

Après certains commentaires que j'ai décidé d'ajouter quelques informations supplémentaires.

La société que je suis en train de travailler à aussi utilise Postgres et surtout SQL Server. Cette base de données ne permettent pas de telles requêtes. Donc, je sais qu'il y a une autre façon de faire (j'écris une solution ci-dessous). Vous devriez aussi savoir ce que vous faites si vous n'avez pas de groupe par toutes les colonnes traitées de la projection ou de l'utilisation des fonctions d'agrégation. Sinon, le laisser être!

J'ai choisi la solution ci-dessus, parce que c'est une question spécifique. Tom voulez obtenir le récent post pour chaque auteur, dans un site wordpress. Dans mon esprit, c'est négligeable pour l'analyse si un auteur ne plus d'un post par seconde. Wordpress devrait même interdire par son spam-le double-post de détection. Par expérience, je sais qu'il y a vraiment un avantage significatif dans les performances de faire un de ces sales group by avec MySQL. Mais si vous savez ce que vous faites, alors vous pouvez le faire! J'ai cette sale groupes dans les applications où je suis professionnellement responsable de. Ici, j'ai des tables avec certains mio lignes qui a besoin de 5-15s au lieu de 100++ secondes.

Peut être utile sur certains des avantages et des inconvénients: http://ftp.nchu.edu.tw/MySQL/tech-resources/articles/debunking-group-by-myths.html


SELECT
    wp_posts.*
FROM 
    wp_posts
    JOIN 
    (
        SELECT
            g.post_author
            MAX(g.post_date) AS post_date
        FROM wp_posts as g
        WHERE
            g.post_status='publish'
            AND g.post_type='post'
        GROUP BY g.post_author
    ) as t 
    ON wp_posts.post_author = t.post_author AND wp_posts.post_date = t.post_date

ORDER BY wp_posts.post_date

Mais si ici plus d'un post par seconde pour un auteur, vous obtiendrez plus d'une ligne et pas seulement la dernière.

Maintenant, vous pouvez tourner la roue à nouveau obtenir le poste avec le plus haut Id. Même ici, au moins, c'est pas garanti que vous obtenez vraiment le dernier.

14voto

Lieven Keersmaekers Points 32396

Je ne suis pas sûr de bien comprendre votre exigence, mais l'instruction interne suivante obtient la liste des dernières post_date de chaque auteur et les joint à la table wp_posts pour obtenir un enregistrement complet.

 SELECT  *
FROM    wp_posts wp
        INNER JOIN (
          SELECT  post_author
                  , MAX(post_date) AS post_date
          FROM    wp_posts
          WHERE   post_status = 'publish'
                  AND post_type = 'post'
          GROUP BY
                  post.author
        ) wpmax ON wpmax.post_author = wp.post_author
                   AND wpmax.post_date = wp.post_date
ORDER BY
        wp.post_date DESC
 

12voto

aanton Points 2292

Je pense que @edze réponse est fausse.

Dans le manuel MySQL , vous pouvez lire:

MySQL étend l'utilisation de GROUP BY, de sorte que la liste de sélection peut se référer à nonaggregated colonnes n'est pas désigné dans la clause GROUP BY. Vous pouvez utiliser cette fonction pour obtenir de meilleures performances en évitant les colonnes de tri et de regroupement. Cependant, c'est surtout utile lorsque tous les les valeurs dans chaque nonaggregated colonne nom ne figure pas dans le GROUPE sont les de même pour chaque groupe. Le serveur est libre de choisir n'importe quelle valeur de chaque le groupe, à moins qu'ils sont les mêmes, les valeurs choisies sont durée indéterminée. En outre, la sélection de valeurs de chaque groupe ne peut pas être influencé par l'ajout d'une clause ORDER BY. Le tri de la jeu de résultats se produit après que les valeurs ont été choisies, et ORDER BY n' pas d'incidence sur les valeurs que le serveur choisit.

Deux grandes références:

Désolé, mais je ne peux pas commenter l' @edze réponse à cause de ma réputation, j'ai donc écrit une nouvelle réponse.

7voto

11101101b Points 3343

Faites un GROUP BY après le ORDER BY en encapsulant votre requête avec le GROUP BY comme ceci:

 SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t GROUP BY t.author
 

4voto

Alex Points 61

Que pensez-vous de ceci?? Semble travailler pour moi

 SELECT wp_posts.post_author, MAX(wp_posts.post_date), wp_posts.status, wp_posts.post_type
FROM wp_posts
    WHERE wp_posts.post_status='publish'
    AND wp_posts.post_type='post'
    GROUP BY wp_posts.post_author
 

Cela m'amène tous les auteurs avec le post_date le plus à jour ... Avez-vous identifié un problème ici ?? Je ne

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