左连接计数干扰左连接总和

时间:2018-12-18 20:09:55

标签: mysql sql

当我添加一个左联接以获取外部表的计数时,其将其他左联接表的总和值与该计数相乘,在这里我也不能使用不同的总和,因为两个值可以相同:

SELECT c.id as company_id, SUM(ct.amount) as total_billed, count(l.id) as load_count
FROM tbl_companies c
LEFT JOIN tbl_company_transactions ct ON c.id = ct.company_id
LEFT JOIN tbl_loads l ON c.id = l.company_id
GROUP BY c.id;

3 个答案:

答案 0 :(得分:2)

您需要预汇总数据:

SELECT c.id as company_id, ct.total_billed,  
       l.load_count
FROM tbl_companies c LEFT JOIN
     (SELECT ct.company_id, SUM(ct.amount) as total_billed
      FROM tbl_company_transactions ct
      GROUP BY ct.company_id
     ) ct
     ON c.id = ct.company_id LEFT JOIN
     (SELECT l.company_id, COUNT(*) as load_count
      FROM tbl_loads l
      GROUP BY l.company_id
     ) l
     ON c.id = l.company_id;

如您所见,JOIN乘以行数并影响聚合。

答案 1 :(得分:1)

您可以隔离汇总统计信息,然后再加入结果。

WITH 
tranStats AS (
    SELECT company_id, SUM(amount) AS total_billed
    FROM tbl_company_transactions
    GROUP BY company_id
),
loadStats AS (
    SELECT company_id, COUNT(1) AS load_count
    FROM tbl_loads
    GROUP BY company_id
)
SELECT id, total_billed, load_count
FROM tbl_companies c
LEFT JOIN tranStats t ON t.company_id = c.id
LEFT JOIN loadStats l ON l.company_id = c.id

答案 2 :(得分:0)

戈登的答案具有更高的可伸缩性,但是对于此特定查询,您只需要一个子查询-由于预聚合数据上的联接可能无法使用索引,因此这可能也会提高性能。

E

要掌握的重要事情是,如果您需要诸如SELECT c.id as company_id, SUM(ct.amount) as total_billed, l.load_count FROM tbl_companies c LEFT JOIN tbl_company_transactions ct ON c.id = ct.company_id LEFT JOIN ( SELECT company_id, count(*) as load_count FROM tbl_loads GROUP BY company_id ) l ON c.id = l.company_id GROUP BY c.id; SUM()之类的聚合函数的结果,则在执行多个行的多个连接时需要小心。