У меня есть две таблицы (счета и налоги) в MySQL:Можно ли избежать этого подзапроса?
Invoices:
- id
- account_id
- issued_at
- total
- gross_amount
- country
Taxes:
- id
- invoice_id
- tax_name
- tax_rate
- taxable_amount
- tax_amount
Я пытаюсь retrive отчет, как этот
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
Идея в том, что счет-фактура имеет отношение has_many
с налогами. Таким образом, счет-фактура может иметь или нет налоги. В отчете должна быть указана общая сумма (total_amount
) для данной страны (учитывается если она включает налоги) и указать, какая часть этой общей суммы облагается налогом (taxable_amount
) за конкретный налог.
Мой текущий подход это один:
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
Ну, это работает, но для реальных данных (тысячи записей), это очень медленно, как select
подзапрос для извлечения total_amount
бежится для каждой строки Отчет. Я не могу сделать LEFT JOIN taxes
с прямым SUM(gross_amount)
как группы GROUP BY
по налоговому названию и курсу, и мне нужно показать общее количество собранных за страну независимо от того, была ли налогооблагаемая сумма или нет. Есть ли более быстрая альтернатива этому?
Спасибо за ответ. Да, идеальный случай будет иметь таблицу с уже сохраненным отчетом, действующим как кеш. Этот запрос необходим для создания отчета в первый раз, поэтому я могу иметь таблицу отчетов, заполненную данными для работы с предстоящими заданиями cron. – John
@John тогда не должно быть никаких проблем, если запрос занял несколько секунд дольше. Это так, как есть! –