用两个日期对两个表中的两列进行求和

时间:2018-01-03 15:35:51

标签: sql sql-server

我为一家CPG公司工作,需要创建一份报告,将上个月交付的单位与下个月的预测进行比较。 (简单地说,我们的预测工具偶尔会搞砸,这有助于确定预测何时关闭。)

我的问题是我的SQL查询正确地总结了预测销售额,但是总交付量的总和并不尊重我在WHERE子句中的日期 - 它是对查询可以追溯的总交付量的总和达到。

这是我的问题:

SELECT
    DelUnits.Customer, DelUnits.ObsText01,
    FinalFcst.SKU, FinalFcst.Customer,
    SUM(DelUnits.Value) AS TotalDelivered,
    SUM(FinalFcst.FinalFcst) AS ForecastSales
FROM 
    DelUnits
LEFT JOIN 
    FinalFcst ON DelUnits.Customer = FinalFcst.Customer
WHERE 
    (FinalFcst.DT >= '2018-01-01' and FinalFcst.DT <= '2018-01-31')
    AND (DelUnits.Date >= '2017-12-01' and DelUnits.Date <= '2017-12-31')
    AND DelUnits.ObsText01 = '10_LB'
    AND FinalFcst.SKU = '10_LB'
GROUP BY 
    DelUnits.Customer, DelUnits.ObsText01, FinalFcst.SKU, FinalFcst.Customer

同样,查询似乎可以正确地用于最终预测(总结预测在1/1/18 - 1/31/18之间),但总结了客户的整个交付历史。我不明白为什么它不会总结12/1/17 - 12/31/17的交付历史。

sample data

感谢您的帮助!

4 个答案:

答案 0 :(得分:3)

据推测,FinalFcst只有一行。因此,要么将其包含在GROUP BY子句中,要么使用MAX()代替SUM()

max(FinalFcst.FinalFcst) as ForecastSales

答案 1 :(得分:1)

表之间有很多关系。最终,您需要SUM()一个表,然后加入另一个表以创建一对多关系,或者最终复制记录。

我最喜欢的方法是派生表:

SELECT C.Customer, 
       C.ObsText01,
       FC.SKU,
       C.TotalDelivered,
       SUM(FC.FinalFcst) ForecastSales
FROM (SELECT SUM(Value) TotalDelivered, Customer, ObsText01
      FROM DelUnits
      WHERE Date >= '2017-12-01' AND Date <= '2017-12-31'
      AND ObsText01 = '10_LB'
      GROUP BY Customer) C
LEFT JOIN FinalFcst FC ON C.Customer = FC.Customer
                      AND FC.DT >= '2018-01-01' 
                      AND FC.DT <= '2018-01-31'
                      AND FC.SKU = '10_LB'
GROUP BY C.Customer, C.ObsText01, FC.SKU, C.TotalDelivered

一些事项:将您的预测表过滤器添加到联接谓词,因为WHERE中的那些过滤器会在INNER JOIN中创建LEFT JOIN。还从select和组中删除了FC.Customer,因为它与C.Customer是多余的。

答案 2 :(得分:1)

实现此目的的一种方法是在2个不同的查询中计算TotalDelivered和ForecastSales,然后将它们连接在一起。

试试这个:

SELECT DelUnits.customer, 
       DelUnits.obstext01, 
       FinalFcst.sku, 
       FinalFcst.customer, 
       totaldelivered, 
       forecastsales 
FROM   (SELECT customer, 
               obstext01, 
               Sum(value) AS TotalDelivered 
        FROM   delunits 
        WHERE  date >= '2017-12-01' 
               AND date <= '2017-12-31'  
               AND obstext01 = '10_LB' 
        GROUP  BY customer, 
                  obstext01) DelUnits 
LEFT JOIN (SELECT customer, 
                    sku, 
                    Sum(finalfcst) AS ForecastSales 
            FROM   finalfcst 
            WHERE  dt >= '2018-01-01' 
                   AND dt <= '2018-01-31' 
                   AND sku = '10_LB' 
            GROUP  BY customer, 
                    sku) FinalFcst  ON DelUnits.customer = FinalFcst.customer 

答案 3 :(得分:0)

也许您可以尝试创建临时表来计算交付历史记录。我不确定SQL Server的措辞,但是这样的话:

WITH DEL_HIST AS
(SELECT DelUnits.Customer,
DelUnits.ObsText01,
sum(DelUnits.Value) as TotalDelivered,
FROM DelUnits
Where(DelUnits.Date >= '2017-12-01' and DelUnits.Date <= '2017-12-31')
and DelUnits.ObsText01 = '10_LB'
Group By DelUnits.Customer, DelUnits.ObsText01)
SELECT
DEL_HIST.Customer,
DEL_HIST.ObsText01,
FinalFcst.SKU,
FinalFcst.Customer,
DEL_HIST.TotalDelivered,
sum(FinalFcst.FinalFcst) as ForecastSales
FROM DEL_HIST
left join FinalFcst ON DelUnits.Customer = FinalFcst.Customer
Where (FinalFcst.DT >= '2018-01-01' and FinalFcst.DT <= '2018-01-31')
and FinalFcst.SKU = '10_LB'
Group By DelUnits.Customer, DelUnits.ObsText01, FinalFcst.SKU, FinalFcst.Customer