我为一家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的交付历史。
感谢您的帮助!
答案 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