加入后不正确的SUM

时间:2013-02-26 23:17:18

标签: mysql sql

我试图以三种不同的方式从一列中获取数据。我正在处理供应商优惠和客户接受的优惠(然后成为项目)。

我想从他们所有的项目中获得总成本,完成与否。其次,我们正在抓住当前的节约,即目前开放项目的节省。最后,我需要找到提供给他们的总金额他们尚未采取行动

我有前两个用这个查询处理:

SELECT SUM(osh.Savings) as YTD,
       SUM(case when p.current_status < 3 then Savings end) AS "Open Savings"
FROM OfferSuggestionHeader osh LEFT JOIN
     Projects p
     ON p.offer_id = osh.OfferID
WHERE p.uid = '1'

到目前为止一切顺利。当我开始加入必要的表来抓住最后一块时,问题出现了。这是单数查询的样子(并且可以工作):

SELECT SUM(ofh.Savings)
from OfferSuggestionHeader ofh
LEFT JOIN OfferSuggestionDetail osd
on ofh.OfferID = osd.OfferID
LEFT JOIN Facilities f
on osd.FacilityID = f.id
LEFT JOIN UserFacility uf
on f.id = uf.fid
LEFT JOIN Users u
on uf.uid = u.uid
WHERE u.uid = 1
AND ofh.OfferID NOT IN(SELECT offer_id FROM Projects WHERE uid = 1)

我已经尝试了六种不同的混合方式,所有这些都没有成功。似乎它是多次加起来的数字或类似的东西。

感谢您提供任何帮助或指示。

编辑:---------------

所以这是一个查询,它执行必要的连接以尝试在保持CASE语句存在的同时获得大的总数:

SELECT (osh.Savings) as "Potential", 
    (case when p.current_status < 3 then osh.Savings else null end) AS "Open Savings",
    (case when p.uid=1 then osh.Savings else null end) AS "YTD"
FROM OfferSuggestionHeader osh
LEFT JOIN OfferSuggestionDetail osd
    ON osd.OfferID = osh.OfferID
LEFT JOIN UserFacility uf
    ON uf.fid = osd.FacilityID
LEFT JOIN Projects p
    ON p.uid = uf.uid
WHERE p.uid = '1'

我删除了SUM部分,看看有些人建议会发生什么。果然,我得到了每个值的三个记录。

enter image description here

这有助于更好地澄清问题吗?

编辑#2:------------ 根据要求,以下是各个工作查询:

YTD:

/*YTD Savings*/
SELECT SUM(osh.Savings) as YTD
FROM Projects p
LEFT JOIN OfferSuggestionHeader osh
    ON p.offer_id = osh.OfferID
WHERE p.uid = 1

目前有效/开放:

/*total from open projects*/
SELECT SUM(osh.Savings) as TotalOpen
FROM Projects p
LEFT JOIN OfferSuggestionHeader osh
    ON p.offer_id = osh.OfferID
WHERE p.uid = 1 AND p.current_status < 3

最后,潜在节省的总和:

/*POTENTIAL*/
SELECT SUM(ofh.Savings) as Potential
from OfferSuggestionHeader ofh
LEFT JOIN OfferSuggestionDetail osd
on ofh.OfferID = osd.OfferID
LEFT JOIN Facilities f
on osd.FacilityID = f.id
LEFT JOIN UserFacility uf
on f.id = uf.fid
LEFT JOIN Users u
on uf.uid = u.uid
WHERE u.uid = 1
AND ofh.OfferID NOT IN(SELECT offer_id FROM Projects WHERE uid = 1)

1 个答案:

答案 0 :(得分:1)

Shibormot可能是正确的,你的OfferSuggestionDetail在OfferSuggestionHeader中的每一行都有多行。当您加入它们时,ofh.savings字段在连接的每一行上都是相同的。然后,当你总结它时,它会乘以细节线的数量。

- 编辑使用您的三个单独查询: 如果您使用查询2,则可以重写它: 目前有效/开放:

SELECT SUM(CASE WHEN p.current_status < 3 osh.Savings ELSE 0 END ) as TotalOpen
FROM Projects p
LEFT JOIN OfferSuggestionHeader osh
    ON p.offer_id = osh.OfferID
WHERE p.uid = 1 

确认它能满足您的需求。如果是,它现在具有与Query 2相同的FROM子句和相同的WHERE子句,因此它们可以组合在一起:

SELECT SUM(osh.Savings) as YTD
      ,SUM(CASE WHEN p.current_status < 3 osh.Savings ELSE 0 END ) as TotalOpen
FROM Projects p
LEFT JOIN OfferSuggestionHeader osh
    ON p.offer_id = osh.OfferID
WHERE p.uid = 1 

MySql支持选择列表中本身 SELECT的列。

如果我将您的第三个查询放入上面的组合查询中,我会得到: (人们可能会稍微清理那个内部的,但它应该起作用。)

SELECT SUM(osh.Savings) as YTD
      ,SUM(CASE WHEN p.current_status < 3 osh.Savings ELSE 0 END ) as TotalOpen

, (SELECT SUM(ofh2.Savings) as Potential
   from OfferSuggestionHeader ofh2
   LEFT JOIN OfferSuggestionDetail osd2 on ofh2.OfferID = osd2.OfferID
   LEFT JOIN Facilities f2 on osd2.FacilityID = f2.id
   LEFT JOIN UserFacility uf2 on f2.id = uf2.fid
   LEFT JOIN Users u on uf2.uid = u2.uid
   WHERE ofh.OfferID = ofh2.OfferID 
   AND u2.uid = 1
   AND ofh2.OfferID NOT IN(SELECT offer_id FROM Projects WHERE uid = 1
  )


FROM Projects p
LEFT JOIN OfferSuggestionHeader osh
    ON p.offer_id = osh.OfferID
WHERE p.uid = 1 

希望能让你更近一步。