【问题标题】:MySQL query combining sums from multiple tablesMySQL查询组合来自多个表的总和
【发布时间】:2017-07-06 18:36:48
【问题描述】:

我有以下查询,它试图生成所有客户、他们的项目、每个项目花费的时间、发票总额和发票总数的列表。

SELECT
    c.name as client,
    p.name as project,
    SUM(t.hours) as hours,
    SUM(ci.amount) as invoice_amount,
    COUNT(ci.id) as number_invoices
FROM
    projects p
    INNER JOIN client_master c ON c.harvest_id = p.client_id
    INNER JOIN timesheet t ON t.project_id = p.id 
    LEFT OUTER JOIN projects_contracts pc ON pc.project_id = p.id
    INNER JOIN contracts_invoices ci ON ci.contract_id = pc.contract_id
GROUP BY
    c.name,
    p.name
ORDER BY
    c.name, 
    p.name,
    t.hours

当我运行查询时,“小时数”计算正确,但 invoice_amount 和 number_invoices 的总和/计数并没有根据上下文加入到项目中,而是加入到表中的发票总数中。如果我注释掉 sum() 中的一个,那么我会得到正确的值,但当它们都在时不会。

预期结果

客户 A,项目 1, 1000, $10,000, 2

客户 A,项目 2,5000,5000 美元,1

客户 B,项目 1,100,3000 美元,1

实际结果

客户 A,项目 1, 1000, $150,000, 20

客户 A,项目 2, 5000, $50,000, 81

客户 B,项目 1, 100, $83000, 12

我尝试过使用 grouping 和 join 语句,但没有成功。有什么简单的我忽略了还是需要完全重写?

【问题讨论】:

标签: mysql sql join


【解决方案1】:

由于发票依赖于合同,而合同是可选的(左连接), 使该联接也成为左联接。

SELECT
    c.name as client,
    p.name as project,
    SUM(t.hours) as hours,
    SUM(ci.amount) as invoice_amount,
    COUNT(ci.id) as number_invoices
FROM
    projects p
    INNER JOIN client_master c 
        ON c.harvest_id = p.client_id
    INNER JOIN timesheet t 
        ON t.project_id = p.id 
    LEFT JOIN projects_contracts pc 
        ON pc.project_id = p.id
    LEFT JOIN contracts_invoices ci 
        ON ci.contract_id = pc.contract_id
GROUP BY
    c.name,
    p.name
ORDER BY
    c.name, 
    p.name,
    t.hours

【讨论】:

  • 感谢斯隆。当我在收到以下消息之前完成此操作时,MySQL 说:文档 #1104 - SELECT 将检查超过 MAX_JOIN_SIZE 行;检查您的 WHERE 并使用 SET SQL_BIG_SELECTS=1 或 SET MAX_JOIN_SIZE=# 如果 SELECT 没问题
  • 表格有多少行? MAX_JOIN_SIZE 设置为多少?你试过改变它吗?
  • 我在查询的开头添加了 SET SQL_BIG_SELECT=1 语句。这次它产生了结果,但数据仍然不正确。我得到了 CLIENT,PROJECT,148.92,142956.00,54 我应该收到 CLIENT,PROJECT,148.92,$10,000, 3
  • 查看我对您原始帖子的问题。还有上面的那些。
  • 最大的表是时间表,此时只有 60K 条目。其余的最多可能有 100 行。我得到的数字比他们应该的要高得多。就好像我得到了整个表格的总和,而不仅仅是项目。这有帮助吗?
【解决方案2】:

这可能不是最好的方法,但我敢打赌它有效

SELECT
    c.name as client,
    p.name as project,
    t.hours as hours,
    ci.amount as invoice_amount,
    ci.count as number_invoices
FROM
    projects p
    INNER JOIN client_master c 
        ON c.harvest_id = p.client_id
    INNER JOIN (SELECT project_id, SUM(hours) AS hours FROM timesheet GROUP BY project_id) t
        ON t.project_id = p.id 
    LEFT OUTER JOIN projects_contracts pc 
        ON pc.project_id = p.id
    LEFT OUTER JOIN (SELECT contract_id, SUM(amount) AS amount, COUNT(DISTINCT id) AS count FROM contracts_invoices GROUP BY contract_id) ci
        ON ci.contract_id = pc.contract_id
GROUP BY
    c.name,
    p.name
ORDER BY
    c.name, 
    p.name,
    t.hours

【讨论】:

  • 似乎已经做到了。它产生了几个发票金额为零的项目,但这很好,因为我可以把它们放在哪里。现在......尝试将其余的公式重新放入......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-06
  • 2016-11-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多