Maison >base de données >tutoriel mysql >Explication détaillée de la véritable méthode d'ouverture de MySql Group par fonction !

Explication détaillée de la véritable méthode d'ouverture de MySql Group par fonction !

藏色散人
藏色散人avant
2022-01-27 17:10:072573parcourir

Cet article vous présentera la bonne façon d'ouvrir le groupe MySql par fonction. J'espère qu'il vous sera utile !

Lors de l'utilisation de la fonction de groupe pour filtrer l'ensemble de résultats, quelques problèmes rencontrés et solutions [Recommandé : Tutoriel vidéo mysql]

1.

Il y a deux tables

Table d'articles (table de messages un à plusieurs)

t_posts : oid, posts_name
Table de messages (table d'articles plusieurs à un)
t_comment : oid, posts_id, msg_content, create_time

2. Analyse des exigences

Requête du dernier contenu de réponse de chaque article

3.Écriture SQL

select 
  tp.oid,
  tp.posts_name,
  tc.msg_content,
  tc.create_time
from t_posts tp 
left join t_comment tc on tp.oid = tc.posts_id
group by tp.oid having create_time = max(create_time)

Supposons qu'il y ait deux articles A et B (l'ordre des enregistrements de réponse dans la base de données est cohérent avec ce qui suit)

<p>A有一个回复记录时间为: 2019-09-10   <br>A有一个回复记录时间为: 2019-09-11   <br>B有一个回复记录时间为: 2019-09-01   <br>B有一个回复记录时间为: 2019-09-09<br></p>
Lorsque vous exécutez le SQL ci-dessus, vous constaterez qu'un grand nombre d'enregistrements sont perdus dans l'ensemble de résultats et que les résultats sont faux. Après avoir interrogé les données, nous savons que

mysql a. est exécuté après group by, c'est-à-dire en regroupant d'abord, puis en filtrant, mais comme il y a plus de deux enregistrements de message,

donc le résultat défini après le regroupement ne prendra que le premier message de chaque message comme information d'enregistrement après le regroupement. cette fois, si vous utilisez create_time = max(create_time)
alors, max (create_time) est la durée maximale du regroupement actuel

est : 2019-09-10 et 2019-09-09

Donc le sql ci-dessus perdra l'ensemble de résultats

4. Transformez le SQL

car il sait que le regroupement sera fusionné L'ensemble de résultats répété est celui avec le plus petit numéro de ligne, pouvons-nous donc modifier le SQL comme suit ??

select 
  tp.oid,
  tp.posts_name,
  tc.msg_content,
  tc.create_time
from t_posts tp 
left join t_comment tc on tp.oid = tc.posts_id
group by tp.oid having create_time = max(create_time)
-- 下面的是新增的sql
order by tc.create_time desc
Après l'avoir exécuté, j'ai découvert que cela ne fonctionnait toujours pas, ce qui prouve que order by est après group by & have

Plus tard, j'y ai réfléchi, puis-je ne pas l'avoir ? Que diriez-vous d'utiliser directement order by pour optimiser le ? résultats groupés ?

ayant create_time = max(create_time)

select 
  tp.oid,
  tp.posts_name,
  tc.msg_content,
  tc.create_time
from t_posts tp 
left join t_comment tc on tp.oid = tc.posts_id
group by tp.oid 
order by tc.create_time desc
L'erreur d'ensemble de résultats n'affecte pas les résultats de regroupement. Les ensembles de résultats en double sont toujours fusionnés en fonction du regroupement minimum de rownum, puis dans le tri

. 5. La version modifiée ultime

Parce que l'ordre par ne peut affecter que le groupe par, est-il possible de trier le résultat défini avant le groupe par, puis de le regrouper ?

select * from (
  select 
    tp.oid,
    tp.posts_name,
    tc.msg_content,
    tc.create_time
  from t_posts tp 
  left join t_comment tc on tp.oid = tc.posts_id
  order by tc.create_time desc
) t 
group by t.oid
J'ai trouvé que ce n'est toujours pas facile à utiliser, mais la sous-requête est en effet triée en premier

Après l'interrogation (expliquer), il s'avère que l'ordre par de la sous-requête a été optimisé Solution :

    Utilisez la limite 99999 dans la sous-requête
  1. Utilisez la condition Where dans la sous-requête, create_time. = (sélectionnez max (create_time) dans le groupe t_comment par oid)
  2. select * from (
      select 
        tp.oid,
        tp.posts_name,
        tc.msg_content,
        tc.create_time
      from t_posts tp 
      left join t_comment tc on tp.oid = tc.posts_id
      order by tc.create_time desc limit 9999
    ) t 
    group by t.oid

Terminé

Points de connaissances supplémentaires :

Différence entre les versions mysql5.5 et mysql 5.7 : version 5.7+, si la limite n'est pas utilisée, regrouper par optimisera la commande d'ici

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer