2016-11-28 4 views
2

Ich habe mehrere Tabellen, die eine Rückerstattungsanforderung von seiner Kalkulationsphase bis zu seiner Rechnungsstellung verfolgen, Aufzeichnung von Werbebuchungen und deren Werte in jeder Phase der Anfrage.Vereinfachen Sie die Summe der Summe Abfragen in Mysql

Um die Summen für jede Spesenkategorie in jeder Phase zu erhalten, summierte ich sie mit einer Auswahl - was ich nicht herausfinden konnte, ist eine effiziente Möglichkeit, ihre Gesamtsummen für die gesamte Phase zu summieren, ohne eine andere zu tun Summenanforderung Da dies Hunderttausende Zeilen abfragt, leidet die Reaktionszeit. Die aktuelle Methode dauert knapp 4,59 Sekunden - während, wenn ich die Gesamtsumme Summen entfernen dauert es 4,02 Sekunden - einen Rat, wie die ursprünglichen Summen an Alias ​​eine Gesamtsumme zu erhalten wäre höchst willkommen sein:

SELECT p.program_name, p.id as program_id, p.entity_id, a.id as account_id, 


(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 9 and c.account_id = a.id) as NIPLoanCost, 
(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 2 and c.account_id = a.id) as AcquisitionCost, 
(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 3 and c.account_id = a.id) as PreDemoCost, 
(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 4 and c.account_id = a.id) as DemolitionCost, 
(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 5 and c.account_id = a.id) as GreeningCost, 
(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 6 and c.account_id = a.id) as MaintenanceCost, 
(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 7 and c.account_id = a.id) as AdministrationCost, 
(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 8 and c.account_id = a.id) as OtherCost, 

(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE c.account_id = a.id) 
as TotalCost, 

/* I have removed the other 4 table's requests that follow this same methodology */ 

FROM programs p, accounts a WHERE p.entity_id = a.entity_id; 
+0

Was ist die Beziehung zwischen 'a.entity_id' und' a.id'? –

+0

Entität (Entitäts-ID) ist die Organisation, der das Konto (a.id) gehört, zu dem die Elemente gehören. Eine Entität kann viele Konten besitzen, aber ein Konto kann nur eine Einheit haben. –

+0

Ich habe Ihnen unten eine Antwort gegeben, die Sie vielleicht etwas ändern müssen. –

Antwort

4

Sie können Verwenden Sie eine bedingte Aggregation mit einem Join zur cost_items-Tabelle, um alle Unterabfragen zu ersetzen. So etwas sollte funktionieren:

SELECT p.program_name, 
     p.id as program_id, 
     p.entity_id, 
     t.* 
FROM programs p 
INNER JOIN accounts a 
    ON p.entity_id = a.entity_id 
INNER JOIN 
(
    SELECT a.id AS account_id, 
      SUM(CASE WHEN c.expense_category_id = 9 THEN c.amount ELSE 0 END) AS NIPLoanCost, 
      SUM(CASE WHEN c.expense_category_id = 2 THEN c.amount ELSE 0 END) AS AcquisitionCost, 
      SUM(CASE WHEN c.expense_category_id = 3 THEN c.amount ELSE 0 END) AS PreDemoCost, 
      SUM(CASE WHEN c.expense_category_id = 4 THEN c.amount ELSE 0 END) AS DemolitionCost, 
      SUM(CASE WHEN c.expense_category_id = 5 THEN c.amount ELSE 0 END) AS GreeningCost, 
      SUM(CASE WHEN c.expense_category_id = 6 THEN c.amount ELSE 0 END) AS MaintenanceCost, 
      SUM(CASE WHEN c.expense_category_id = 7 THEN c.amount ELSE 0 END) AS AdministrationCost, 
      SUM(CASE WHEN c.expense_category_id = 8 THEN c.amount ELSE 0 END) AS OtherCost, 
      COALESECE(SUM(c.amount), 0) AS TotalCost 
    FROM accounts a 
    LEFT JOIN cost_items c 
     ON a.id = c.account_id 
    GROUP BY a.id 
) t 
    ON a.id = t.account_id 

Beachten Sie, dass der Fehler mit Ihrem ursprünglichen Ansatz korrelierte Unterabfragen wie diese:

(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 9 and c.account_id = a.id) 

Für jeden Datensatz in dem verbundenen Produkt der programs und accounts Tabelle Sie waren Ausgabe einer separaten Abfrage (viele von ihnen tatsächlich), die die gesamte cost_items Tabelle gescannt wurde, um die Summe zu bestimmen. In meinem Ansatz machen wir einen einzigen Durchlauf durch die Verbindung von accounts und cost_items, und hier wird die Zeit gespeichert.

+0

Wow ... lass mich versuchen und sehen. –

+0

Sieht so aus, als ob die ON a.id = t.id ON sein sollte. A.id = t.account_id - macht diese Änderung - es gibt mir die Summen sehr schnell (.05 Sek.) - aber ich sehe nicht wie ich die bekommen soll Gesamtsumme aller Elemente zusammen –

+0

Wenn Sie etwas komplexer als das wollen, dann sollten Sie wirklich Ihre Frage aufräumen und Beispieldaten mit der erwarteten Ausgabe hinzufügen. –