Mysql
 sql >> Database >  >> RDS >> Mysql

MySQL SUM() fornisce un totale errato

Stai riscontrando aggregate fanout issue . Ciò si verifica ogni volta che la tabella primaria in una query di selezione ha meno righe di una tabella secondaria a cui è unita. Il join risulta in righe duplicate. Pertanto, quando vengono applicate le funzioni aggregate, agiscono su righe aggiuntive.

Qui la tabella primaria si riferisce a quella in cui vengono applicate le funzioni aggregate. Nel tuo esempio,
* SUM(matters.fee)>> aggregazione su tabella matters .
* SUM(advicetime*advicefee)>> aggregazione su tabella actions
* fixedfee='Y'>> dove la condizione nella tabella matters

Per evitare il problema del fanout:
* Applica sempre gli aggregati alla tabella più granulare in un join.
* A meno che due tabelle non abbiano una relazione uno a uno, non applicare le funzioni di aggregazione ai campi da entrambe le tabelle.
* Ottieni i tuoi aggregati separatamente tramite diverse sottoquery e poi combina il risultato. Questo può essere fatto in un'istruzione SQL, oppure puoi esportare i dati e poi farlo.

Domanda 1:

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

Domanda 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 non soffrire di fanout. A questo punto puoi esportarli entrambi e gestire il risultato in php. Oppure puoi combinarli in SQL:

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

Infine, SUM non accetta una parola chiave DISTINCT . DISTINCT è disponibile solo per COUNT e GROUP_CONCAT funzioni aggregate. Quello che segue è un pezzo di SQL non valido

SUM(DISTINCT matters.fee) AS totfixed