问题描述
Hello Stack社区,
我不确定标题是否准确,但是我试图创建一个表,该表按产品代码跟踪每日使用量。目前,我的代码会删除未使用产品的日期,而我需要将其显示为0。
我的想法是,通过使用日期表中的日期,我的LEFT OUTER JOIN字段上带有ISNULL的日期将产生0,但是不。
这是我的代码,带有输出的屏幕截图,红色方块突出显示我需要将其显示为0的缺失日期记录的地方:
SELECT
DD.DATE,DE.PRODUCT_CODE,--OOC = OUT OF CONTEXT,EITHER ISN'T CHARGEABLE OR ISN'T CURRENTLY ACTIVE
ISNULL(SUM(LIDV.QTY - LIDV.QTYSUB),0),OD.LOCATION,OD.soURCE
FROM Dim_Date AS DD
LEFT OUTER JOIN ORDERv_DatesDays AS OD ON DD.DATE BETWEEN OD.SHIP_DATE AND OD.adjRETURN_DATE
LEFT OUTER JOIN FACT_Orders_LIDs AS LIDV ON LIDV.soRDERID_DAX = OD.soRDERID_DAX
LEFT OUTER JOIN DIM_ECODES AS DE ON DE.PRODUCT_CODE = LIDV.eCODE
WHERE
--DD.DATE = '3/1/2017' AND
DD.DATE BETWEEN '1/1/2017' AND EOMONTH( DATEADD( MONTH,-1,CURRENT_TIMESTAMP ) ) AND
DE.PRODUCT_CODE = '07316-' AND
YEAR(DD.DATE) = 2017
GROUP BY
DD.DATE,OD.soURCE
ORDER BY
DD.DATE
我还认为,由于我不是sql专家,所以也许我只需要创建一个表,其中包含指定日期范围内的每个产品代码和日期,但是我也尝试创建该表。
感谢您的协助,如果我需要添加更多信息,请告诉我我所缺少的信息。
解决方法
此WHERE谓词正在杀死您的左联接:
DE.PRODUCT_CODE = '07316-' AND
如果product_code 07316在2月24日至4月6日之间没有“借出”(或其他借项),则所有行都将如下所示:
DATE PRODUCT_CODE INUSE LOCATION
2017-02-25 NULL NULL NULL
2017-02-26 NULL NULL NULL
2017-02-27 NULL NULL NULL
2017-02-28 NULL NULL NULL
...
2017-04-05 NULL NULL NULL
但是,product_code
中的NULL意味着where子句询问“ NULL是否等于07316-吗?”答案是 false ,因此结果集中的行散发错误
考虑
LEFT OUTER JOIN DIM_ECODES AS DE
ON
DE.PRODUCT_CODE = LIDV.eCODE AND
DE.PRODUCT_CODE = '07316-'
您可能还希望在SELECT块中进行一些更改:
'07316-' as PRODUCT_CODE,COALESCE(INUSE,0) AS INUSE
这样写可能对您来说更有意义:
FROM
Dim_Date AS DD
LEFT OUTER JOIN
(
SELECT
OD.SHIP_DATE,OD.adjRETURN_DATE,LIDV.QTY,LIDV.QTYSUB,OD.LOCATION,OD.SOURCE
FROM
ORDERv_DatesDays AS OD
INNER JOIN FACT_Orders_LIDs AS LIDV ON LIDV.SORDERID_DAX = OD.SORDERID_DAX
INNER JOIN DIM_ECODES AS DE ON DE.PRODUCT_CODE = LIDV.eCODE
WHERE
DE.PRODUCT_CODE = '07316-'
) x
ON DD.DATE BETWEEN x.SHIP_DATE AND x.adjRETURN_DATE
WHERE
这是“日期列表在左侧”和“任何相关数据,已经合并在一起并且在右侧位置”
还应注意,如果您要针对多个产品代码执行此操作,那么如果2月28日同时使用产品07316和07317,则仅防止单个日期行,您需要:
FROM
(
SELECT DISTINCT DD.DATE,DE.PRODUCT_CODE
FROM Dim_Date AS DD CROSS JOIN DIM_ECODES DE
WHERE ..date range clause..
)
这将获取日期列表,并将其与产品代码列表交叉,因此可以确定至少有这两行:
2017-02-28 07316-
2017-02-28 07317-
然后,当您按日期和产品代码对产品进行左连接时,这些行的数据都将在左连接中保留下来,并与null关联:
2017-02-28 07316- NULL NULL
2017-02-28 07317- NULL NULL
如果不进行交叉操作,您将只有一行(产品代码中为空)