所以我很幸运能够为我们的应用程序优化查询,这对于我们获得的数据来说花费的时间太长了。我们正在寻找的数据并不复杂,但是糟糕的数据库设计使它变得更加困难(这很棒,因为我是一年前设计它的人)。
一般的想法是我们试图计算每个客户的总销售额(他们购买增加余额的东西)和总支付(他们为余额支付的钱)。
表格:
客户
销售(发票):
付款(account_payments)
交易(invoice_transactions)
如果用户进行了促销,则该信息会记录在invoices
和invoice_transactions
中,其中invoice_transactions具有包含customer_id的发票记录的invoice_id。
如果用户进行付款,则信息将记录在account_payments
和invoice_transactions
中,invoice_transaction的invoice_id为NULL,account_payments包含transaction_id以及customer_id。
我知道,这太可怕了......我以为我很聪明!好吧,我认为问题通过了,并提出了一个不错的解决方案:
SELECT SQL_NO_CACHE
c.company,
(SELECT SUM(amount) FROM sales),
(SELECT SUM(amount) FROM payments)
FROM customers c
JOIN invoices i ON i.customer_id = c.id
JOIN invoice_transactions sales ON i.invoice_id = sales.id
JOIN account_payments ap ON ap.customer_id = c.id
JOIN invoice_transactions payments ON ap.transaction_id = payments.id
除了给我一个错误之外什么都没做“#1146 - 表'db.sales'不存在”。我猜它与连接之前读取的子查询有关,但老实说我不知道。不幸的是,我不知道另一种解决这个问题的方法......如果有人能帮我一把,我们非常感激!
答案 0 :(得分:2)
我认为最好的方法是将销售和付款元素分成子查询,您当前的方法是在进行汇总之前将所有付款与所有发票交叉加入。
SELECT c.ID,
c.Company,
COALESCE(Sales.Amount, 0) AS Sales,
COALESCE(Payments.Amount, 0) AS Payments
FROM Customers c
LEFT JOIN
( SELECT Customer_ID, SUM(Amount) AS Amount
FROM Invoices
INNER JOIN invoice_transactions
ON Invoice_ID = Invoices.ID
GROUP BY Customer_ID
) As Sales
ON Sales.Customer_ID = c.ID
LEFT JOIN
( SELECT Customer_ID, SUM(Amount) AS Amount
FROM Account_Payments
INNER JOIN invoice_transactions tr
ON tr.ID = Transaction_ID
GROUP BY Customer_ID
) AS Payments
ON Payments.Customer_ID = c.ID;
这将包括没有发票且没有付款的客户。您可以将左连接更改为内连接以对其进行操作。
答案 1 :(得分:1)
您的查询没有意义。
完成所有加入之后,为什么不使用“from”子句中的表:
SELECT c.company, SUM(sales.amount), SUM(payments.amount)
FROM customers c JOIN invoices i ON i.customer_id = c.id JOIN
invoice_transactions sales ON i.invoice_id = sales.id JOIN
account_payments ap ON ap.customer_id = c.id JOIN
invoice_transactions payments ON ap.transaction_id = payments.id
group by c.company
仅在“from”子句中为表提供别名不会使其在查询中其他位置的子查询中可用。
我还添加了一个GROUP BY子句,因为您的查询似乎是由公司聚合的。