Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL SUM() gibt falsche Summe an

Sie haben ein aggregate fanout issue . Dies geschieht immer dann, wenn die primäre Tabelle in einer Auswahlabfrage weniger Zeilen enthält als eine sekundäre Tabelle, mit der sie verknüpft ist. Die Verknüpfung führt zu doppelten Zeilen. Wenn also Aggregatfunktionen angewendet werden, wirken sie auf zusätzliche Zeilen.

Hier bezieht sich die primäre Tabelle auf diejenige, in der Aggregatfunktionen angewendet werden. In Ihrem Beispiel
* SUM(matters.fee)>> Aggregation auf Tabelle matters .
* SUM(advicetime*advicefee)>> Aggregation auf Tabelle actions
* fixedfee='Y'>> wo Bedingung auf Tabelle matters ist

So vermeiden Sie das Fanout-Problem:
* Wenden Sie die Aggregate immer auf die detaillierteste Tabelle in einem Join an.
* Wenden Sie keine Aggregatfunktionen auf Felder von an, es sei denn, zwei Tabellen haben eine Eins-zu-Eins-Beziehung beide Tabellen.
* Erhalten Sie Ihre Aggregate separat durch verschiedene Unterabfragen und kombinieren Sie dann das Ergebnis. Dies kann in einer SQL-Anweisung erfolgen, oder Sie können die Daten exportieren und dann ausführen.

Abfrage 1:

SELECT SUM(fee) AS totfixed 
FROM matters 
WHERE fixedfee='Y'

Abfrage 2:

SELECT SUM(actions.advicetime*actions.advicefee) AS totbills 
FROM matters  
JOIN actions ON matters.matterid = actions.matterid 
WHERE matters.fixedfee = 'Y'

Query 1 &Query 2 leide nicht unter Fanout. An dieser Stelle können Sie beide exportieren und das Ergebnis in PHP bearbeiten. Oder Sie können sie in SQL kombinieren:

SELECT query_2.totbills, query_1.totfixed
FROM (SELECT SUM(fee) AS totfixed 
    FROM matters 
    WHERE fixedfee='Y') query_1,

    (SELECT SUM(actions.advicetime*actions.advicefee) AS totbills 
    FROM matters  
    JOIN actions ON matters.matterid = actions.matterid 
    WHERE matters.fixedfee = 'Y') query_2

Zum Schluss SUM nimmt kein Schlüsselwort DISTINCT . DISTINCT ist nur für COUNT verfügbar und GROUP_CONCAT aggregierte Funktionen. Das Folgende ist ein Stück ungültiges SQL

SUM(DISTINCT matters.fee) AS totfixed