【问题标题】:LEFT JOIN with SUM not returning correct values [duplicate]SUM 的 LEFT JOIN 未返回正确的值 [重复]
【发布时间】:2020-06-10 21:39:31
【问题描述】:

我有一张包含各种成本明细的发票表。 我也有一个包含杂项费用的链接表。 关系是一张发票与许多杂项费用

当我执行 SUM() 并且杂项成本表 (RIGHT) 上存在多行时,发票表 (LEFT) 中的值乘以找到的行数。

DB 小提琴:https://www.db-fiddle.com/f/9CKGRShXPoT3k4Wcm83fVD/5

对于 LABOUR、PARTS、POLS 和 SUBLET 的原始查询结果不正确:

SELECT  SUM(ad.labour_cost) AS LABOUR,
    SUM(ad.part_cost) AS PARTS,
    SUM(ad.pol_cost) AS POLS,
    SUM(ad.sublet_cost) AS SUBLET,
    SUM(am.misc_sales_amt)  AS MISC
FROM AdvisorSalesData ad 
LEFT JOIN AdvisorMiscSalesData am 
  ON (ad.customer_id=am.customer_id AND ad.invoice_no=am.invoice_no)
WHERE ad.customer_id IN (3)

调整后的查询 - 删除了 INNER JOIN 并在 misc 表上尝试了单个 SELECT,但 MISC 的结果不正确(NULL):

SELECT  SUM(ad.labour_cost) AS LABOUR,
    SUM(ad.part_cost) AS PARTS,
    SUM(ad.pol_cost) AS POLS,
    SUM(ad.sublet_cost) AS SUBLET,
    (SELECT SUM(misc_sales_amt) FROM AdvisorMiscSalesData WHERE customer_id IN (3) AND invoice_no=ad.invoice_no ) AS MISC
FROM AdvisorSalesData ad 
WHERE ad.customer_id IN (3)

如何调整以在一个查询中获得所有 5 列的正确结果?

【问题讨论】:

  • 一对多还是多对多?
  • 预期结果是什么?

标签: mysql sql mariadb-10.1


【解决方案1】:

聚合之前加入:

SELECT SUM(ad.labour) AS LABOUR,
       SUM(ad.parts) AS PARTS,
       SUM(ad.pols) AS POLS,
       SUM(ad.sublet) AS SUBLET,
       SUM(am.misc)  AS MISC
FROM (SELECT customer_id, invoice_no,
             SUM(ad.labour_cost) AS LABOUR,
             SUM(ad.part_cost) AS PARTS,
             SUM(ad.pol_cost) AS POLS,
             SUM(ad.sublet_cost) as sublet
      FROM AdvisorSalesData ad 
      GROUP BY customer_id, invoice_no
     ) ad LEFT JOIN
     (SELECT customer_id, invoice_no,
             SUM(am.misc_sales_amt) AS MISC
      FROM AdvisorMiscSalesData am 
      GROUP BY customer_id, invoice_no
     ) am
     ON ad.customer_id = am.customer_id AND    
        ad.invoice_no = am.invoice_no
WHERE ad.customer_id IN (3);

Here 是一个 dbfiddle。

您可以在子查询中重复过滤以获得更好的性能:

SELECT SUM(ad.labour) AS LABOUR,
       SUM(ad.parts) AS PARTS,
       SUM(ad.pols) AS POLS,
       SUM(ad.sublet) AS SUBLET,
       SUM(am.misc)  AS MISC
FROM (SELECT customer_id, invoice_no,
             SUM(ad.labour_cost) AS LABOUR,
             SUM(ad.part_cost) AS PARTS,
             SUM(ad.pol_cost) AS POLS,
             SUM(ad.sublet_cost) as sublet
      FROM AdvisorSalesData ad 
      WHERE ad.customer_id IN (3)
      GROUP BY customer_id, invoice_no
     ) ad LEFT JOIN
     (SELECT customer_id, invoice_no,
             SUM(am.misc_sales_amt) AS MISC
      FROM AdvisorMiscSalesData am 
      WHERE ad.customer_id IN (3)
      GROUP BY customer_id, invoice_no
     ) am
     ON ad.customer_id = am.customer_id AND    
        ad.invoice_no = am.invoice_no
WHERE ad.customer_id IN (3);

【讨论】:

  • 戈登,正确的小提琴:db-fiddle.com/f/9CKGRShXPoT3k4Wcm83fVD/6你必须在完成后点击更新,否则你只是在复制旧的。干杯
  • 好的。这会返回正确的结果 - 谢谢......但是,当我将它添加回我的代码时,它需要 269 秒才能执行......
猜你喜欢
  • 2021-09-12
  • 2013-08-28
  • 1970-01-01
  • 2013-11-28
  • 1970-01-01
  • 2013-09-28
  • 2012-03-27
  • 2018-12-15
  • 1970-01-01
相关资源
最近更新 更多