我在mysql中有两个表(发票和税金):
Invoices:
- id
- account_id
- issued_at
- total
- gross_amount
- country
Taxes:
- id
- invoice_id
- tax_name
- tax_rate
- taxable_amount
- tax_amount
我试图回复像这样的报告
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
)(如果包含税款则为regardess)
并指明该总金额的哪一部分应征税(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
的{{1}}子查询,因此它非常慢。
我不能通过税名和费率将total_amount
与LEFT JOIN taxes
组作为SUM(gross_amount)
组,我需要显示每个国家/地区收集的总金额,无论金额是否已征税。有更快的替代方案吗?
答案 0 :(得分:0)
我不知道使用此查询的确切用例,但问题是您尝试构建数据库的方式,您试图一次性获取整个数据。
理想情况下,您应该运行您拥有的查询并将其存储在另一个表(摘要表)中,然后根据需要直接从摘要表中进行查询。如果您在Invoices表中有新条目,那么您可以使用该查询在每个条目上运行,或通过cronjob定期更新汇总表。