Heim >Datenbank >MySQL-Tutorial >Warum aggregiert mein SQL COUNT(*) alle Zeilen, anstatt nach ID und Poster zu gruppieren?
*SQL COUNT() Falsches Aggregieren von Zeilen: Eine häufige Gefahr**
Eine häufige Herausforderung bei SQL-Abfragen besteht darin, dass die Aggregatfunktion COUNT(*)
unerwartet alle Zeilen zählt, anstatt die beabsichtigte Gruppierung durchzuführen. Dies ist häufig auf eine falsche Platzierung oder Auslassung der GROUP BY
-Klausel zurückzuführen.
Lassen Sie uns eine problematische Abfrage und ihre Lösung untersuchen:
Die ursprüngliche Abfrage zielte darauf ab, Zeilen basierend auf dem „Aura“-Status zu zählen, gruppiert nach „Poster“ und „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>
Das erwartete Ergebnis, eine Anzahl von „Aura“-Vorkommen pro „Poster“- und „ID“-Kombination (z. B. ID 1, Poster 2 mit 2 Aura-Instanzen), wurde nicht erreicht. Die Funktion COUNT(*)
in der Unterabfrage hat fälschlicherweise alle Zeilen von messages_aura
.
Die Lösung: Korrekt gruppieren mit GROUP BY
Das Problem liegt im Fehlen einer GROUP BY
-Klausel in der Unterabfrage, die mit messages_aura
verknüpft ist. Die korrigierte Abfrage lautet:
<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>
Durch das Hinzufügen von GROUP BY AuraID, AuraStatus
zur inneren SELECT
-Anweisung zählt die Funktion COUNT(*)
nun korrekt Zeilen für jede eindeutige Kombination von AuraID
und AuraStatus
und erzeugt so die gewünschten gruppierten Ergebnisse. Dadurch wird sichergestellt, dass Aura
auf Zeilenebene genau gezählt wird. Die äußere GROUP BY
-Klausel aggregiert dann die Ergebnisse basierend auf ID
und Poster
.
Das obige ist der detaillierte Inhalt vonWarum aggregiert mein SQL COUNT(*) alle Zeilen, anstatt nach ID und Poster zu gruppieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!