Votre solution utilise une extension de GROUPE PAR la clause qui permet au groupe de certains champs (dans ce cas, il suffit d' post_author
):
GROUP BY wp_posts.post_author
et sélectionnez nonaggregated colonnes:
SELECT wp_posts.*
qui ne sont pas énumérés dans la clause group by, ou qui ne sont pas utilisés dans une fonction d'agrégation (MIN, MAX, COUNT, etc.).
Utilisation correcte de l'extension à la clause GROUP BY
Ceci est utile lorsque toutes les valeurs de non-agrégées colonnes sont égales pour chaque ligne.
Par exemple, supposons que vous avez une table GardensFlowers
(name
le jardin, flower
qui pousse dans le jardin):
INSERT INTO GardensFlowers VALUES
('Central Park', 'Magnolia'),
('Hyde Park', 'Tulip'),
('Gardens By The Bay', 'Peony'),
('Gardens By The Bay', 'Cherry Blossom');
et vous voulez extraire toutes les fleurs qui pousse dans un jardin, où de multiples fleurs. Ensuite, vous devez utiliser une sous-requête, par exemple, vous pouvez utiliser ceci:
SELECT GardensFlowers.*
FROM GardensFlowers
WHERE name IN (SELECT name
FROM GardensFlowers
GROUP BY name
HAVING COUNT(DISTINCT flower)>1);
Si vous avez besoin d'extraire toutes les fleurs qui sont les seules fleurs à le garder au lieu de cela, vous pouvez simplement modifier la condition d'AVOIR d' HAVING COUNT(DISTINCT flower)=1
, mais aussi MySql vous permet d'utiliser ceci:
SELECT GardensFlowers.*
FROM GardensFlowers
GROUP BY name
HAVING COUNT(DISTINCT flower)=1;
pas de sous-requête, pas du SQL standard, mais en plus simple.
Une utilisation incorrecte de l'extension à la clause GROUP BY
Mais qu'advient-il si vous SÉLECTIONNEZ non-agrégées des colonnes qui sont sans égal pour chaque ligne? Qui est la valeur que MySql choisit pour cette colonne?
Il ressemble à MySql choisit toujours la PREMIÈRE valeur qu'elle rencontre.
Assurez-vous que la première valeur qu'elle rencontre est exactement la valeur que vous voulez, vous devez appliquer un GROUPE PAR un ordre de requête, d'où la nécessité de figu utilisant une sous-requête. Vous ne pouvez pas le faire sans avoir recours.
Compte tenu de l'hypothèse que MySql choisit toujours la première ligne qu'il rencontre, vous êtes correcly trier les lignes avant de le GROUPE. Mais malheureusement, si vous lisez attentivement la documentation, vous remarquerez que cette hypothèse n'est pas vrai.
Lors de la sélection de la non-agrégées colonnes qui ne sont pas toujours les mêmes, MySql est libre de choisir n'importe quelle valeur, de sorte que le montant de la valeur qu'il montre, en réalité, est de durée indéterminée.
Je vois que cette astuce pour obtenir la première valeur d'un non-agrégées colonne est beaucoup utilisé, et c'est souvent/presque toujours, je l'utilise aussi parfois (à mes risques et périls). Mais puisqu'il n'est pas documentée, vous ne pouvez pas compter sur ce comportement.
Ce lien (merci ypercube!) GROUPE PAR astuce a été optimisé à l'écart montre une situation dans laquelle la même requête renvoie des résultats différents entre MySql et MariaDB, probablement en raison d'un autre moteur d'optimisation.
Donc, si cette astuce fonctionne, c'est juste une question de chance.
La accepté de répondre à l'autre question
La accepté de répondre à l'autre question ne semble pas correct du tout pour moi. Je pense que c'est faux:
HAVING wp_posts.post_date = MAX(wp_posts.post_date)
wp_posts.post_date
est un non-agrégées de la colonne, et sa valeur sera officiellement indéterminée, mais il sera vraisemblablement le premier post_date
rencontrées. Mais depuis que le GROUPE PAR la ruse est appliqué à une table non ordonnée, il n'est pas sûr de qui est le premier post_date
rencontrées.
Il sera probablement retourne les messages qui sont les seuls postes d'un seul auteur, mais ce n'est pas toujours certaine.
Une solution possible
Je pense que cela pourrait être une solution possible:
SELECT wp_posts.*
FROM wp_posts
WHERE id IN (
SELECT max(id)
FROM wp_posts
WHERE (post_author, post_date) = (
SELECT post_author, max(post_date)
FROM wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY post_author
) AND wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY post_author
)
Sur la requête interne, je suis de retour le maximum de post date pour chaque auteur. Je suis ensuite en prenant en considération le fait que le même auteur pourrait théoriquement avoir deux postes en même temps, donc je suis arriver au maximum de l'ID. Et puis je suis retourner toutes les lignes ceux maximale Id. Il peut être fait plus rapidement en utilisant des jointures au lieu de la clause.
(si vous êtes sûr que l'ID est toujours en augmentation, et si ID1>ID2 signifie également que post_date1>post_date2 la requête pourrait être beaucoup plus simple, mais je ne suis pas sûr si c'est le cas).