Ordre MySQL par avant groupe par

243

Il y a beaucoup de questions similaires à trouver ici, mais je ne pense pas que quelqu'un y réponde correctement.

Je vais continuer de le courant le plus populaire question et d' utiliser leur exemple , si c'est bien.

La tâche dans ce cas est d'obtenir le dernier message pour chaque auteur dans la base de données.

L'exemple de requête produit des résultats inutilisables car ce n'est pas toujours le dernier message renvoyé.

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

La réponse actuellement acceptée est

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

Malheureusement, cette réponse est tout simplement erronée et, dans de nombreux cas, produit des résultats moins stables que la requête d'origine.

Ma meilleure solution consiste à utiliser une sous-requête du formulaire

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

Ma question est alors simple: existe-t-il de toute façon de commander des lignes avant de les regrouper sans recourir à une sous-requête?

Edit : Cette question faisait suite à une autre question et les spécificités de ma situation sont légèrement différentes. Vous pouvez (et devez) supposer qu'il existe également un wp_posts.id qui est un identifiant unique pour cette publication particulière.

Rob Forrest
la source
2
Comme vous l'avez mentionné dans les commentaires des réponses données, il pourrait être possible d'avoir certains messages avec le même horodatage. Si oui, veuillez donner un exemple avec des données et le résultat attendu. Et veuillez décrire pourquoi vous attendez ce résultat. post_authoret post_datene suffisent pas pour obtenir une ligne unique, donc il doit y en avoir plus pour obtenir une ligne unique parpost_author
Sir Rufo
@SirRufo Vous avez raison, j'ai ajouté une modification pour vous.
Rob Forrest
There are plenty of similar questions to be found on here but I don't think that any answer the question adequately.C'est à cela que servent les primes.
Courses de légèreté en orbite le
@LightnessRacesinOrbit, si la question actuelle a déjà une réponse acceptée qui, à mon avis, est fausse, que suggéreriez-vous de faire?
Rob Forrest
1
Vous vous demandez pourquoi vous avez accepté une réponse qui utilise une sous-requête - lorsque votre question demande clairement ... "" Y a-t-il de toute façon des lignes à ordonner avant de les regrouper sans recourir à une sous-requête? "???
TV-C-15

Réponses:

373

Utiliser un ORDER BY dans une sous-requête n'est pas la meilleure solution à ce problème.

La meilleure solution pour obtenir l' max(post_date)auteur par est d'utiliser une sous-requête pour renvoyer la date maximale, puis la joindre à votre table à la fois à la post_authordate maximale et à la date maximale.

La solution devrait être:

SELECT p1.* 
FROM wp_posts p1
INNER JOIN
(
    SELECT max(post_date) MaxPostDate, post_author
    FROM wp_posts
    WHERE post_status='publish'
       AND post_type='post'
    GROUP BY post_author
) p2
  ON p1.post_author = p2.post_author
  AND p1.post_date = p2.MaxPostDate
WHERE p1.post_status='publish'
  AND p1.post_type='post'
order by p1.post_date desc

Si vous disposez des exemples de données suivants:

CREATE TABLE wp_posts
    (`id` int, `title` varchar(6), `post_date` datetime, `post_author` varchar(3))
;

INSERT INTO wp_posts
    (`id`, `title`, `post_date`, `post_author`)
VALUES
    (1, 'Title1', '2013-01-01 00:00:00', 'Jim'),
    (2, 'Title2', '2013-02-01 00:00:00', 'Jim')
;

La sous-requête va retourner la date maximale et l'auteur de:

MaxPostDate | Author
2/1/2013    | Jim

Ensuite, puisque vous joignez cela à la table, sur les deux valeurs, vous retournerez tous les détails de ce message.

Voir SQL Fiddle avec démo .

Pour développer mes commentaires sur l'utilisation d'une sous-requête pour renvoyer avec précision ces données.

MySQL ne vous oblige pas à GROUP BYchaque colonne que vous incluez dans la SELECTliste. Par conséquent, si vous n'avez qu'une GROUP BYseule colonne mais renvoyez 10 colonnes au total, rien ne garantit que les autres valeurs de colonne qui appartiennent à celle post_authorqui est renvoyée. Si la colonne n'est pas dans unGROUP BY MySQL, choisissez la valeur à renvoyer.

L'utilisation de la sous-requête avec la fonction d'agrégation garantira que l'auteur et le message corrects sont retournés à chaque fois.

En guise de remarque, alors que MySQL vous permet d'utiliser un ORDER BYdans une sous-requête et vous permet d'appliquer un GROUP BYà pas toutes les colonnes de la SELECTliste, ce comportement n'est pas autorisé dans d'autres bases de données, y compris SQL Server.

Taryn
la source
4
Je vois ce que vous avez fait là-bas, mais cela renvoie simplement la date à laquelle le message le plus récent a été rédigé, pas la ligne entière pour ce dernier message.
Rob Forrest
1
@RobForrest, c'est ce que fait la jointure. Vous renvoyez la date de publication la plus récente dans la sous-requête par auteur, puis vous revenez à votre wp_postssur les deux colonnes pour obtenir la ligne complète.
Taryn
7
@RobForrest D'une part, lorsque vous appliquez le GROUP BYà une seule colonne, rien ne garantit que les valeurs des autres colonnes seront toujours correctes. Malheureusement, MySQL permet à ce type de SELECT / GROUPing de se produire, contrairement à d'autres produits. Deuxièmement, la syntaxe de l'utilisation d'un ORDER BYdans une sous-requête alors qu'il est autorisé dans MySQL n'est pas autorisée dans d'autres produits de base de données, y compris SQL Server. Vous devez utiliser une solution qui retournera le résultat correct à chaque exécution.
Taryn
2
Pour la mise à l'échelle, le composé INDEX(post_author, post_date)est important.
Rick James
1
@ jtcotton63 Vrai, mais si vous mettez post_idvotre requête interne, alors techniquement, vous devez également la regrouper, ce qui fausserait probablement vos résultats.
Taryn
20

Votre solution utilise une extension de la clause GROUP BY qui permet de regrouper par certains champs (dans ce cas, juste post_author):

GROUP BY wp_posts.post_author

et sélectionnez des colonnes non agrégées:

SELECT wp_posts.*

qui ne sont pas répertorié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 de la clause GROUP BY

Ceci est utile lorsque toutes les valeurs des colonnes non agrégées sont égales pour chaque ligne.

Par exemple, supposons que vous ayez une table GardensFlowers( namedu jardin, flowerqui 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 poussent dans un jardin, où poussent plusieurs 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 devez extraire toutes les fleurs qui sont les seules fleurs dans le garder à la place, vous pouvez simplement changer la condition HAVING HAVING COUNT(DISTINCT flower)=1, mais MySql vous permet également d'utiliser ceci:

SELECT   GardensFlowers.*
FROM     GardensFlowers
GROUP BY name
HAVING   COUNT(DISTINCT flower)=1;

pas de sous-requête, pas de SQL standard, mais plus simple.

Utilisation incorrecte de l'extension de la clause GROUP BY

Mais que se passe-t-il si vous sélectionnez des colonnes non agrégées qui ne sont pas égales pour chaque ligne? Quelle est la valeur que MySql choisit pour cette colonne?

Il semble que MySql choisisse toujours la PREMIÈRE valeur qu'il rencontre.

Pour vous assurer que la première valeur rencontrée est exactement la valeur souhaitée, vous devez appliquer un GROUP BY à une requête ordonnée, d'où la nécessité d'utiliser une sous-requête. Vous ne pouvez pas le faire autrement.

Étant donné l'hypothèse que MySql choisit toujours la première ligne qu'il rencontre, vous triez correctement les lignes avant le GROUP BY. Mais malheureusement, si vous lisez attentivement la documentation, vous remarquerez que cette hypothèse n'est pas vraie.

Lors de la sélection de colonnes non agrégées qui ne sont pas toujours les mêmes, MySql est libre de choisir n'importe quelle valeur, de sorte que la valeur résultante qu'elle affiche réellement est indéterminée .

Je vois que cette astuce pour obtenir la première valeur d'une colonne non agrégée est beaucoup utilisée, et cela fonctionne généralement / presque toujours, je l'utilise aussi parfois (à mes risques et périls). Mais comme ce n'est pas documenté, vous ne pouvez pas vous fier à ce comportement.

Ce lien (merci ypercube!) L' astuce GROUP BY a été optimisé 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 moteur d'optimisation différent.

Donc, si cette astuce fonctionne, c'est juste une question de chance.

La réponse acceptée à l'autre question me semble fausse:

HAVING wp_posts.post_date = MAX(wp_posts.post_date)

wp_posts.post_dateest une colonne non agrégée, et sa valeur sera officiellement indéterminée, mais ce sera probablement la première post_daterencontrée. Mais puisque l'astuce GROUP BY est appliquée à une table non ordonnée, il n'est pas sûr de savoir quelle est la première post_daterencontrée.

Il retournera probablement des articles qui sont les seuls articles d'un seul auteur, mais même cela n'est pas toujours certain.

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 renvoie la date de publication maximale pour chaque auteur. Je prends ensuite en considération le fait que le même auteur pourrait théoriquement avoir deux messages en même temps, donc je ne reçois que l'ID maximum. Et puis je retourne toutes les lignes qui ont ces ID maximum. Il pourrait être rendu plus rapide en utilisant des jointures au lieu de la clause IN.

(Si vous êtes sûr que cela IDne fait qu'augmenter, et si ID1 > ID2cela signifie également cela post_date1 > post_date2, alors la requête pourrait être rendue beaucoup plus simple, mais je ne suis pas sûr que ce soit le cas).

fthiella
la source
C'est extension to GROUP Byune lecture intéressante, merci pour cela.
Rob Forrest
2
Un exemple où il échoue: l' astuce GROUP BY a été optimisée
ypercubeᵀᴹ
Les colonnes non agrégées dans les expressions sélectionnées avec GROUP BY ne fonctionnent plus par défaut avec MySQL 5.7: stackoverflow.com/questions/34115174/… . Quelle IMHO est beaucoup plus sûre et oblige certaines personnes à écrire des requêtes plus efficaces.
rink.attendant.6
Cette réponse n'utilise-t-elle pas une sous-requête? L'affiche originale ne demande-t-elle pas une solution qui n'utilise PAS de sous-requête?
TV-C-15
1
@ TV-C-15, le problème est lié au recours à la sous-requête, et j'explique pourquoi le recours à une sous-requête ne fonctionnera pas. Même la réponse acceptée utilise une sous-requête mais elle commence à expliquer pourquoi le recours est une mauvaise idée (L' utilisation d'un ORDER BY dans une sous-requête n'est pas la meilleure solution à ce problème )
fthiella
9

Ce que vous allez lire est plutôt hacky, alors n'essayez pas ça à la maison!

En SQL en général, la réponse à votre question est NON , mais en raison du mode détendu de GROUP BY(mentionné par @bluefeet ), la réponse est OUI dans MySQL.

Supposons que vous ayez un index BTREE sur (post_status, post_type, post_author, post_date). À quoi ressemble l'index sous le capot?

(post_status = 'publish', post_type = 'post', post_author = 'user A', post_date = '2012-12-01') (post_status = 'publish', post_type = 'post', post_author = 'user A', post_date = '2012-12-31') (post_status = 'publish', post_type = 'post', post_author = 'user B', post_date = '2012-10-01') (post_status = 'publish', post_type = ' post ', post_author =' user B ', post_date =' 2012-12-01 ')

Autrement dit, les données sont triées par tous ces champs dans l'ordre croissant.

Lorsque vous effectuez un GROUP BYpar défaut, il trie les données par le champ de regroupement ( post_author, dans notre cas; post_status, post_type sont requis par la WHEREclause) et s'il existe un index correspondant, il prend les données pour chaque premier enregistrement dans l'ordre croissant. C'est-à-dire que la requête va récupérer ce qui suit (le premier message pour chaque utilisateur):

(post_status = 'publish', post_type = 'post', post_author = 'user A', post_date = '2012-12-01') (post_status = 'publish', post_type = 'post', post_author = 'user B', post_date = '2012-10-01')

Mais GROUP BYdans MySQL vous permet de spécifier explicitement l'ordre. Et lorsque vous demandez post_userdans l'ordre décroissant, il parcourra notre index dans l'ordre inverse, en prenant toujours le premier enregistrement pour chaque groupe qui est en fait le dernier.

C'est

...
WHERE wp_posts.post_status='publish' AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author DESC

nous donnera

(post_status = 'publish', post_type = 'post', post_author = 'user B', post_date = '2012-12-01') (post_status = 'publish', post_type = 'post', post_author = 'user A', post_date = '2012-12-31')

Maintenant, lorsque vous commandez les résultats du regroupement par post_date, vous obtenez les données que vous vouliez.

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

NB :

Ce n'est pas ce que je recommanderais pour cette requête particulière. Dans ce cas, j'utiliserais une version légèrement modifiée de ce que suggère @bluefeet . Mais cette technique pourrait être très utile. Jetez un œil à ma réponse ici: Récupération du dernier enregistrement dans chaque groupe

Pièges : les inconvénients de l'approche sont que

  • le résultat de la requête dépend de l'index, ce qui est contraire à l'esprit du SQL (les index ne devraient accélérer que les requêtes);
  • l'index ne sait rien de son influence sur la requête (vous ou quelqu'un d'autre à l'avenir pourriez trouver l'index trop gourmand en ressources et le modifier d'une manière ou d'une autre, brisant les résultats de la requête, pas seulement ses performances)
  • si vous ne comprenez pas comment fonctionne la requête, vous oublierez probablement l'explication dans un mois et la requête vous embrouillera, vous et vos collègues.

L'avantage est la performance dans les cas difficiles. Dans ce cas, les performances de la requête doivent être les mêmes que dans la requête de @ bluefeet, en raison de la quantité de données impliquées dans le tri (toutes les données sont chargées dans une table temporaire puis triées; btw, sa requête nécessite également l' (post_status, post_type, post_author, post_date)index) .

Ce que je suggérerais :

Comme je l'ai dit, ces requêtes font perdre du temps à MySQL pour trier des quantités potentiellement énormes de données dans une table temporaire. Si vous avez besoin de pagination (c'est-à-dire que LIMIT est impliqué), la plupart des données sont même supprimées. Ce que je ferais, c'est de minimiser la quantité de données triées: c'est-à-dire de trier et de limiter un minimum de données dans la sous-requête, puis de rejoindre la table entière.

SELECT * 
FROM wp_posts
INNER JOIN
(
  SELECT max(post_date) post_date, post_author
  FROM wp_posts
  WHERE post_status='publish' AND post_type='post'
  GROUP BY post_author
  ORDER BY post_date DESC
  -- LIMIT GOES HERE
) p2 USING (post_author, post_date)
WHERE post_status='publish' AND post_type='post';

La même requête en utilisant l'approche décrite ci-dessus:

SELECT *
FROM (
  SELECT post_id
  FROM wp_posts
  WHERE post_status='publish' AND post_type='post'
  GROUP BY post_author DESC
  ORDER BY post_date DESC
  -- LIMIT GOES HERE
) as ids
JOIN wp_posts USING (post_id);

Toutes ces requêtes avec leurs plans d'exécution sur SQLFiddle .

newtover
la source
C'est une technique intéressante que vous avez là-bas. Deux choses: vous dites de ne pas essayer ça à la maison, quels sont les pièges potentiels? deuxièmement, vous mentionnez une version légèrement modifiée de la réponse de bluefeet, que serait-ce?
Rob Forrest
Merci pour cela, c'est intéressant de voir quelqu'un attaquer le problème d'une manière différente. Comme mon ensemble de données est loin de vos 18 millions de lignes et plus, je ne pense pas que les performances soient aussi cruciales que la maintenabilité, donc je pense que vos options ultérieures sont probablement plus adaptées. J'aime l'idée de la limite à l'intérieur de la sous-requête.
Rob Forrest
8

Essaye celui-là. Obtenez simplement la liste des dernières dates de publication de chaque auteur . C'est tout

SELECT wp_posts.* FROM wp_posts WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post' AND wp_posts.post_date IN(SELECT MAX(wp_posts.post_date) FROM wp_posts GROUP BY wp_posts.post_author) 
sanchitkhanna26
la source
@Rob Forrest, vérifiez ma solution. J'espère que cela résout votre question!
sanchitkhanna26
1
Je suis désolé, je ne pense pas que cela fonctionnerait. Par exemple, si l'auteur 1 et l'auteur 2 publient quelque chose le 01/02/13 et que l'auteur 2 poste quelque chose de nouveau le 08/02/13, les 3 messages seront retournés. Oui, le champ datetime inclut le temps, donc la situation est moins probable, mais en aucun cas elle n'est garantie sur un ensemble de données suffisamment grand.
Rob Forrest
+1 pour utiliser le post_date IN (select max(...) ...). C'est plus efficace que de faire un groupe par sous-sélection, voir dev.mysql.com/doc/refman/5.6/en/subquery-optimization.html
Seaux
juste pour clarifier, c'est seulement plus optimal si vous avez indexé post_author.
Seaux
1
IN ( SELECT ... )est beaucoup moins efficace que l'équivalent JOIN.
Rick James
3

Non. Il est inutile de classer les enregistrements avant de les regrouper, car le regroupement va modifier le jeu de résultats. La voie de sous-requête est la voie préférée. Si cela va trop lentement, vous devrez changer la conception de votre table, par exemple en stockant l'id du dernier article pour chaque auteur dans une table séparée, ou introduire une colonne booléenne indiquant pour chaque auteur lequel de son article est le dernier une.

Dennisch
la source
Dennish, comment répondriez-vous aux commentaires de Bluefeet selon lesquels ce type de requête n'est pas une syntaxe SQL correcte et n'est donc pas portable sur toutes les plateformes de base de données? On craint également qu'il n'y ait aucune garantie que cela produise à chaque fois les résultats corrects.
Rob Forrest
2

Utilisez simplement la fonction max et la fonction group

    select max(taskhistory.id) as id from taskhistory
            group by taskhistory.taskid
            order by taskhistory.datum desc
Konstantin XFlash Stratigenas
la source
3
Que se passe-t-il si celui dont l'ID est le plus élevé n'est pas le dernier affiché? Un exemple de ceci pourrait être que l'auteur a gardé son poste en projet pendant une longue période avant de le poster.
Rob Forrest
0

Pour récapituler, la solution standard utilise une sous-requête non corrélée et ressemble à ceci:

SELECT x.*
  FROM my_table x
  JOIN (SELECT grouping_criteria,MAX(ranking_criterion) max_n FROM my_table GROUP BY grouping_criteria) y
    ON y.grouping_criteria = x.grouping_criteria
   AND y.max_n = x.ranking_criterion;

Si vous utilisez une ancienne version de MySQL ou un ensemble de données assez petit, vous pouvez utiliser la méthode suivante:

SELECT x.*
  FROM my_table x
  LEFT
  JOIN my_table y
    ON y.joining_criteria = x.joining_criteria
   AND y.ranking_criteria < x.ranking_criteria
 WHERE y.some_non_null_column IS NULL;  
fraise
la source
Quand vous parlez de version ancienne, sur quelle version de MySQL cela fonctionnerait-il? Et désolé non, l'ensemble de données est assez grand dans mon exemple.
Rob Forrest
Cela fonctionnera (lentement) sur n'importe quelle version. Les versions antérieures ne peuvent pas utiliser de sous-requêtes.
Strawberry
Oui, la méthode # 2 (la version que j'ai essayée est d' ici ) ne fonctionnera pas sur un grand ensemble de données (millions de lignes), génère une erreur de connexion perdue . La méthode n ° 1 prend ~ 15 secondes pour exécuter une requête. J'ai d'abord voulu éviter d'utiliser des requêtes imbriquées, mais cela m'a fait reconsidérer. Je vous remercie!
aexl
@TheSexiestManinJamaica Oui. Peu de choses ont changé en 3,5 ans. En supposant qu'une requête est efficace en soi, le temps nécessaire à l'exécution de la requête dépend en grande partie de la taille de l'ensemble de données, de la disposition des index et du matériel disponible.
Strawberry
-1

** Les sous-requêtes peuvent avoir un impact négatif sur les performances lorsqu'elles sont utilisées avec de grands ensembles de données **

Requête d'origine

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; 

Requête modifiée

SELECT p.post_status,
       p.post_type,
       Max(p.post_date),
       p.post_author
FROM   wp_posts P
WHERE  p.post_status = "publish"
       AND p.post_type = "post"
GROUP  BY p.post_author
ORDER  BY p.post_date; 

parce que j'utilise maxdans le select clause==> max(p.post_date)il est possible d'éviter les requêtes de sous-sélection et l'ordre par la colonne max après le groupe par.

guykaplan
la source
1
Cela renvoie en effet la date de publication la plus récente par auteur, mais rien ne garantit que le reste des données renvoyées se rapporte à la publication avec la date de publication la plus récente.
Rob Forrest
@RobForrest -> Je ne comprends pas pourquoi? c'est une bonne idée d'élaborer votre réponse et de simplement rejeter les réclamations. Autant que je sache, les données sont assurément liées car j'utilise la clause where pour filtrer les données associées.
guykaplan
1
Dans une certaine mesure, vous avez tout à fait raison, chacun des 4 champs que vous sélectionnez se rapportera à cette post_date maximale, mais cela ne répond pas à la question qui a été posée. Par exemple, si vous avez ajouté le post_id, ou le contenu du post, alors ces colonnes ne seraient pas assurées de provenir du même enregistrement que la date maximale. Pour obtenir votre requête ci-dessus pour renvoyer le reste des détails du message, vous devez exécuter une deuxième requête. Si la question portait sur la recherche de la date du message le plus récent, alors oui, votre réponse conviendrait.
Rob Forrest
@guykaplan, les sous-requêtes ne sont pas lentes. La taille de l'ensemble de données n'a pas d'importance. Cela dépend de la façon dont vous l'utilisez. Voir percona.com/blog/2010/03/18/when-the-subselect-runs-faster
Pacerier
@Pacerier: l'article montre en effet comment vous pouvez tirer parti des performances des sous-requêtes, mais j'aimerais vous voir convertir le scénario donné pour qu'il fonctionne mieux. et la taille des données est importante, encore une fois dans l'article que vous avez publié, vous supposez qu'il n'y a qu'une seule table avec laquelle travailler. la taille des données n'est pas la taille de la ligne, mais la taille de la complexité. cela dit, si vous travaillez avec une très grande table (pas beaucoup de tables impliquées), la sous-requête peut fonctionner beaucoup mieux.
guykaplan
-4

Tout d'abord, n'utilisez pas * dans select, affecte leurs performances et empêche l'utilisation du groupe par et triez par. Essayez cette requête:

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

Lorsque vous ne spécifiez pas la table dans ORDER BY, juste l'alias, ils ordonneront le résultat de la sélection.

Bruno Nardini
la source
Ignorez les select *, ils sont par souci de concision dans cet exemple. Votre réponse est exactement la même que le premier exemple que j'ai donné.
Rob Forrest
L'alias n'a aucun effet sur la ligne à renvoyer ni sur le tri des résultats.
Rob Forrest