如何使用GROUP BY和ORDER BY在多个表中求和?

时间:2019-12-16 17:29:41

标签: mysql

我正尝试将这些查询减少为一个,因此它不是三个单独的查询。除了我现有的方法以外,还有其他更好的方法吗?我还试图将IE的所有总数加起来(发票总数+退款总数+贷记总额)。这些表除客户外没有其他关系,但我不是要按客户分组,只是要日期。任何帮助将不胜感激。

SELECT 
    SUM(qbi.amount) AS invoiced_total,
    DATE_FORMAT(qbi.line_item_date, '%Y-%m-01') AS date
        FROM
            invoices as qbi
        WHERE
            qbi.`line_item_date` BETWEEN '2018-12-01' AND '2019-12-31'
        GROUP BY
            DATE_FORMAT(qbi.`line_item_date`, '%Y-%m-01')
         ORDER BY
            DATE_FORMAT(qbi.`line_item_date`, '%Y-%m-01');
SELECT 
    SUM(amount) AS refund_total,
    DATE_FORMAT(refund_date, '%Y-%m-01') AS refund_date
        FROM
            refunds
        WHERE
            refund_date BETWEEN '2018-12-01' AND '2019-12-31'
        GROUP BY
            DATE_FORMAT(refund_date, '%Y-%m-01')
         ORDER BY
            DATE_FORMAT(refund_date, '%Y-%m-01');
SELECT 
    SUM(amount) AS credit_memo_total,
    DATE_FORMAT(credit_memo_date, '%Y-%m-01') AS credit_memo_date
        FROM
            credit_memos
        WHERE
            credit_memo_date BETWEEN '2018-12-01' AND '2019-12-31'
        GROUP BY
            DATE_FORMAT(credit_memo_date, '%Y-%m-01')
         ORDER BY
            DATE_FORMAT(credit_memo_date, '%Y-%m-01');

2 个答案:

答案 0 :(得分:0)

您通常会加入三个查询。假设所有月份都在三个表中可用,您可以执行以下操作:

SELECT
    i.invoice_month my_month,
    i.invoiced_total,
    r.refund_total,
    c.credit_total,
    i.invoiced_total + r.refund_total + c.credit_total amount_total
FROM (
    SELECT 
        SUM(amount) AS invoiced_total, 
        DATE_FORMAT(line_item_date, '%Y-%m-01') AS invoice_month
    FROM invoices
    WHERE line_item_date BETWEEN '2018-12-01' AND '2019-12-31'
    GROUP BY invoice_month
) i
INNER JOIN (
    SELECT 
        SUM(amount) AS refund_total, 
        DATE_FORMAT(refund_date, '%Y-%m-01') AS refund_month
    FROM refunds
    WHERE refund_date BETWEEN '2018-12-01' AND '2019-12-31'
    GROUP BY refund_month
) r
INNER JOIN (
    SELECT 
        SUM(amount) AS credit_total, 
        DATE_FORMAT(credit_memo_date, '%Y-%m-01') AS credit_month
    FROM credit_memos
    WHERE credit_memo_date BETWEEN '2018-12-01' AND '2019-12-31'
    GROUP BY credit_memo_month
) c
ORDER BY i.invoice_month 

侧面说明:在MySQL中,您可以在GROUP BY子句(和ORDER BY子句)中使用列别名:这有助于缩短查询。

答案 1 :(得分:0)

如果要加入这些查询,还必须使用第4个查询,该查询将返回3个表中的所有不同月份,以防万一它们中缺少月份。
这就是为什么应该对表使用左联接:

SELECT d.date, i.invoiced_total, r.refund_total, c.credit_memo_total,
  COALESCE(invoiced_total, 0) + COALESCE(refund_total, 0) + COALESCE(credit_memo_total, 0) AS total
FROM (
  SELECT DATE_FORMAT(qbi.`line_item_date`, '%Y-%m-01') AS date FROM invoices UNION
  SELECT DATE_FORMAT(refund_date, '%Y-%m-01') FROM refunds UNION
  SELECT DATE_FORMAT(credit_memo_date, '%Y-%m-01') FROM credit_memos
) AS d
LEFT JOIN ( 
  SELECT 
    SUM(qbi.amount) AS invoiced_total,
    DATE_FORMAT(qbi.line_item_date, '%Y-%m-01') AS date
        FROM
            invoices as qbi
        WHERE
            qbi.`line_item_date` BETWEEN '2018-12-01' AND '2019-12-31'
        GROUP BY
            DATE_FORMAT(qbi.`line_item_date`, '%Y-%m-01')
) i ON i.date = d.date
LEFT JOIN (
  SELECT 
    SUM(amount) AS refund_total,
    DATE_FORMAT(refund_date, '%Y-%m-01') AS refund_date
        FROM
            refunds
        WHERE
            refund_date BETWEEN '2018-12-01' AND '2019-12-31'
        GROUP BY
            DATE_FORMAT(refund_date, '%Y-%m-01')
) r ON r.date = d.date
LEFT JOIN (
  SELECT 
    SUM(amount) AS credit_memo_total,
    DATE_FORMAT(credit_memo_date, '%Y-%m-01') AS credit_memo_date
        FROM
            credit_memos
        WHERE
            credit_memo_date BETWEEN '2018-12-01' AND '2019-12-31'
        GROUP BY
            DATE_FORMAT(credit_memo_date, '%Y-%m-01')
) c ON c.date = d.date
WHERE d.date BETWEEN '2018-12-01' AND '2019-12-31'
ORDER BY d.date