Maison >base de données >tutoriel mysql >Pourquoi mon SQL COUNT(*) regroupe-t-il toutes les lignes au lieu de les regrouper par ID et affiche ?
*SQL COUNT() Agrégation incorrecte des lignes : un piège courant**
Un défi fréquent dans les requêtes SQL implique que la COUNT(*)
fonction d'agrégation compte de manière inattendue toutes les lignes au lieu d'effectuer le regroupement prévu. Cela provient souvent d'un placement incorrect ou d'une omission de la clause GROUP BY
.
Examinons une requête problématique et sa solution :
La requête originale visait à compter les lignes en fonction du statut « Aura », regroupées par « Poster » et « ID » :
<code class="language-sql">SELECT `ID`, `To`, `Poster`, `Content`, `Time`, ifnull(`Aura`,0) as `Aura` FROM ( SELECT * FROM ( SELECT DISTINCT * FROM messages m INNER JOIN ( SELECT Friend2 as Friend FROM friends WHERE Friend1 = '1' UNION ALL SELECT Friend1 as Friend FROM friends WHERE Friend2 = '1' ) friends ON m.Poster = friends.`Friend` UNION ALL SELECT DISTINCT *, '1' FROM messages where `Poster`='1' ) var LEFT JOIN ( select `ID` as `AuraID`, `Status` as `AuraStatus`, count(*) as `Aura` from messages_aura ) aura ON (var.Poster = aura.AuraID AND var.ID = aura.AuraStatus) ) final GROUP BY `ID`, `Poster` ORDER BY `Time` DESC LIMIT 10</code>
Le résultat attendu, un décompte des occurrences « Aura » par combinaison « Affiche » et « ID » (par exemple, ID 1, Affiche 2 ayant 2 instances Aura), n'a pas été atteint. La fonction COUNT(*)
dans la sous-requête n'a pas agrégé de manière incorrecte toutes les lignes de messages_aura
.
La solution : regrouper correctement avec GROUP BY
Le problème réside dans l'absence de clause GROUP BY
dans la sous-requête joignant messages_aura
. La requête corrigée est :
<code class="language-sql">SELECT `ID`, `To`, `Poster`, `Content`, `Time`, ifnull(`Aura`,0) as `Aura` FROM ( SELECT * FROM ( SELECT DISTINCT * FROM messages m INNER JOIN ( SELECT Friend2 as Friend FROM friends WHERE Friend1 = '1' UNION ALL SELECT Friend1 as Friend FROM friends WHERE Friend2 = '1' ) friends ON m.Poster = friends.`Friend` UNION ALL SELECT DISTINCT *, '1' FROM messages where `Poster`='1' ) var LEFT JOIN ( select `ID` as `AuraID`, `Status` as `AuraStatus`, count(*) as `Aura` from messages_aura GROUP BY AuraID, AuraStatus -- The crucial addition ) aura ON (var.Poster = aura.AuraID AND var.ID = aura.AuraStatus) ) final GROUP BY `ID`, `Poster` ORDER BY `Time` DESC LIMIT 10</code>
En ajoutant GROUP BY AuraID, AuraStatus
à l'instruction interne SELECT
, la fonction COUNT(*)
compte désormais correctement les lignes pour chaque combinaison unique de AuraID
et AuraStatus
, produisant les résultats groupés souhaités. Cela garantit que Aura
est compté avec précision au niveau de la ligne. La clause GROUP BY
externe regroupe ensuite les résultats en fonction de ID
et Poster
.
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!