2017-02-10 3 views
0

Ich habe zwei Tabellen (Rechnungen und Steuern) in mysql:Ist diese Unterabfrage auswählbar?

Invoices: 
    - id 
    - account_id 
    - issued_at 
    - total 
    - gross_amount 
    - country 

Taxes: 
    - id 
    - invoice_id 
    - tax_name 
    - tax_rate 
    - taxable_amount 
    - tax_amount 

Ich versuche, einen Bericht zu retrive wie diese

rep_month | country | total_amount | tax_name | tax_rate(%) | taxable_amount | tax_amount 
-------------------------------------------------------------------------------------- 
2017-01-01 | ES  | 1000   | TAX1  | 21   | 700   | 147 
2017-01-01 | ES  | 1000   | TAX2  | -15   | 700   | 105 
2016-12-01 | FR  | 100   | TAX4  | 20   | 30    | 6 
2016-12-01 | FR  | 100   | B2B  | 0   | 70    | 0 
2017-01-01 | GB  | 2500   | TAX3  | 20   | 1000   | 200 

Die Idee dahinter ist, dass eine Rechnung eine has_many Beziehung hat mit Steuern. So kann eine Rechnung Steuern haben oder nicht. Der Bericht sollte den gesammelten Gesamtbetrag (total_amount) für ein bestimmtes Land (einschließlich Steuern) anzeigen und angeben, welcher Teil des Gesamtbetrags steuerpflichtig ist (taxable_amount) für eine bestimmte Steuer.

Mein aktueller Ansatz ist diese:

SELECT 
DATE_FORMAT(invoices.issued_at, '%Y-%m-01') AS rep_month, 
invoices.country AS country 
(SELECT sum(docs.gross_amount) 
    FROM invoices AS docs 
    WHERE docs.country = invoices.country 
    AND DATE_FORMAT(docs.issue_date, '%Y-%m-01') = rep_month 
) AS total_amount, 
taxes.tax_name AS tax_name, 
taxes.tax_rate AS tax_rate, 
SUM(taxes.taxable_amount) AS taxable_amount, 
SUM(taxes.tax_amount) AS tax_amount 
FROM invoices 
JOIN taxes ON invoices.id = taxes.document_id 
AND documents.issue_date BETWEEN '2016-01-01' AND '2017-12-31' 
GROUP BY account_id, rep_month, country, tax_name, tax_rate 
ORDER BY country desc 

Nun, dies funktioniert aber für einen echten Datensatz (Tausende von Datensätzen) es ist wirklich langsam, wie die select Unterabfrage zum Abrufen der total_amount das ausgeführt wird für jede Zeile von ist der Bericht. Ich kann keine LEFT JOIN taxes mit einer direkten SUM(gross_amount) als die GROUP BY Gruppen nach Steuern Name und Tarif und ich muss die Summe erhoben pro Land unabhängig davon, ob der Betrag besteuert wurde oder nicht. Gibt es dafür eine schnellere Alternative?

Antwort

0

Ich kenne nicht den genauen Anwendungsfall der Verwendung dieser Abfrage, aber das Problem ist die Art, mit der Sie versuchen, die DB zu strukturieren, Sie versuchen, die gesamten Daten auf einmal zu bekommen.

Idealerweise sollten Sie die vorhandene Abfrage ausführen und in einer anderen Tabelle (Übersichtstabelle) speichern und dann direkt aus der Übersichtstabelle abfragen, wann immer Sie möchten. Und wenn Sie einen neuen Eintrag in der Tabelle Rechnungen haben, können Sie die Abfrage entweder für jeden Eintrag ausführen oder die Übersichtstabelle regelmäßig über einen Cronjob aktualisieren.

+1

Danke für die Antwort. Ja, der ideale Fall wäre, eine Tabelle mit dem bereits gespeicherten Bericht als Cache zu haben. Diese Abfrage wird genau benötigt, um den Bericht zum ersten Mal zu erstellen, damit die Berichtstabelle mit Daten gefüllt werden kann, die mit anstehenden Cron-Jobs arbeiten. – John

+0

@John dann sollte es kein Problem geben, wenn die Abfrage ein paar Sekunden länger dauerte. Es ist richtig so wie es ist! –

Verwandte Themen