不能缺少显示零的天数
Posted
技术标签:
【中文标题】不能缺少显示零的天数【英文标题】:Can't get missing days to show zero 【发布时间】:2019-12-25 23:16:13 【问题描述】:这是我写的 - 我试图让没有交易的日期只显示该字段的零。我已经去谷歌并和我认识的每个人交谈,这应该可行 - 但不是:?
IF OBJECT_ID('tempdb..#D') IS NOT NULL
DROP TABLE #D;
CREATE TABLE #D
(
[Date] [DATE] NOT NULL,
PRIMARY KEY CLUSTERED ([Date] ASC)
);
DECLARE @CurrentDate DATE = GETDATE() - 95;
DECLARE @EndDate DATE = GETDATE();
WHILE @CurrentDate < @EndDate
BEGIN
INSERT INTO #D
(
[Date]
)
SELECT DATE = @CurrentDate;
SET @CurrentDate = DATEADD(DD, 1, @CurrentDate);
END;
--SELECT * FROM #D ORDER BY Date DESC
SELECT ITEM2_NUM AS 'Part Number',
COALESCE(SUM(TRANS_QTY), 0) 'Daily Usage',
D.Date AS 'Usage Date'
FROM #D AS D
LEFT OUTER JOIN dbo.W_INVENTORY_TRANS_F IT
ON IT.GL_DT = D.Date
LEFT JOIN dbo.W_BU_ITEM_D BI
ON BI.BUSINESS_UNIT_WID = IT.BUSINESS_UNIT_WID
AND BI.ITEM_WID = IT.ITEM_WID
WHERE DOCUMENT_TYPE_WID = 22
AND D.Date >= DATEADD(yy, -1, GETDATE())
AND IT.BUSINESS_UNIT_WID = '837'
AND IT.ITEM2_NUM = '10111'
AND BI.STOCKING_TYPE = 'P'
GROUP BY ITEM2_NUM,
D.Date
ORDER BY D.Date DESC;
以下是我得到的结果:
Part Number Daily Usage Usage Date
10111 -331.0000 2019-08-19
10111 -2617.0000 2019-08-16
10111 -418.0000 2019-08-15
10111 -471.0000 2019-08-14
10111 -1158.0000 2019-08-13
10111 -766.0000 2019-08-12
10111 -1385.0000 2019-08-09
这就是我想要的:
Part Number Daily Usage Usage Date
10111 -331 8/19/2019
10111 0 8/18/2019
10111 0 8/17/2019
10111 -2617 8/16/2019
10111 -418 8/15/2019
10111 -471 8/14/2019
10111 -1158 8/13/2019
10111 -766 8/12/2019
10111 0 8/11/2019
10111 0 8/10/2019
10111 -1385 8/9/2019
【问题讨论】:
请在代码问题中给出minimal reproducible example--剪切&粘贴&可运行代码;具有期望和实际输出的示例输入(包括逐字错误消息);标签和版本;明确的规范和解释。这包括您可以提供的最少代码,即您显示的代码可以通过您显示的代码扩展为不正常。 (调试基础。) PS如果你不努力清楚地说出你想要什么,那么你就无法理解、推理、交流或搜索。使用足够多的单词、句子和对部分示例的引用来清楚完整地表达你的意思。 了解 LEFT JOIN ON 返回的内容:INNER JOIN ON 行 UNION ALL 不匹配的左表行,由 NULL 扩展。作为 OUTER JOIN 的一部分,始终知道您想要什么 INNER JOIN。 WHERE 或 INNER JOIN ON 在 OUTER JOIN ON 删除任何由 NULL 扩展的行后,需要右 [sic] 表列不为 NULL,即只留下 INNER JOIN ON 行,即“将 OUTER JOIN 转换为 INNER JOIN”。你有那个。 这是一个常见问题解答。在考虑发布之前,请始终在谷歌上搜索任何错误消息和许多清晰、简洁和准确的问题/问题/目标的措辞,带或不带您的特定字符串、名称和行号以及带和不带“site:***.com”并阅读很多点击和答案。如果您发布问题,请使用一个短语作为标题。请参阅How to Ask 和投票箭头鼠标悬停文本。 Left Outer Join doesn't return all rows from my left table?的可能重复 【参考方案1】:您的where
子句实际上将您的left join
更改为inner join
。
这是因为left join
为在正确表中找不到的行返回空值,而null
与任何东西相比总是返回unknown
,SQL Server 将其解释为false
。
您需要做的是将所有引用右侧表的条件移到 on
子句中。
此外,您正在按 ITEM2_NUM
分组,这没有意义,因为它已经在 where
子句中被过滤掉了。
这应该是您的代码的工作版本(DOCUMENT_TYPE_WID
列除外,我不知道它属于哪个表):
SELECT '10111' AS 'Part Number',
COALESCE(SUM(TRANS_QTY), 0) 'Daily Usage',
D.Date AS 'Usage Date'
FROM #D AS D
LEFT OUTER JOIN dbo.W_INVENTORY_TRANS_F IT
ON IT.GL_DT = D.Date
AND IT.BUSINESS_UNIT_WID = '837'
AND IT.ITEM2_NUM = '10111'
-- I had to guess where this column belongs, it might be on the BI table
AND IT.DOCUMENT_TYPE_WID = 22
LEFT JOIN dbo.W_BU_ITEM_D BI
ON BI.BUSINESS_UNIT_WID = IT.BUSINESS_UNIT_WID
AND BI.ITEM_WID = IT.ITEM_WID
AND BI.STOCKING_TYPE = 'P'
WHERE D.Date >= DATEADD(yy, -1, GETDATE())
GROUP BY D.Date
ORDER BY D.Date DESC;
【讨论】:
【参考方案2】:Zohar 是 100% 正确的 - 如果我最终使用的最终代码会在下面的某个时间点结束。
IF OBJECT_ID('tempdb..#D') IS NOT NULL
DROP TABLE #D;
CREATE TABLE #D
(
[Date] [DATE] NOT NULL,
PRIMARY KEY CLUSTERED ([Date] ASC)
);
DECLARE @CurrentDate DATE = GETDATE() - 95;
DECLARE @EndDate DATE = GETDATE();
WHILE @CurrentDate < @EndDate
BEGIN
INSERT INTO #D
(
[Date]
)
SELECT DATE = @CurrentDate;
SET @CurrentDate = DATEADD(DD, 1, @CurrentDate);
END;
IF OBJECT_ID('tempdb..#DailyUsage') IS NOT NULL
DROP TABLE #DailyUsage;
CREATE TABLE #DailyUsage
(
BU_ITEM_WID INT,
TRANS_QTY DECIMAL(15, 4),
GL_DT DATETIME
);
INSERT INTO #DailyUsage
(
BU_ITEM_WID,
TRANS_QTY,
GL_DT
)
SELECT BU_ITEM_WID,
TRANS_QTY AS 'Daily Usage',
GL_DT
FROM dbo.W_INVENTORY_TRANS_F
WHERE 1 = 1
AND DOCUMENT_TYPE_WID = 22
AND GL_DT >= GETDATE() - 95;
CREATE NONCLUSTERED INDEX [IX_DailyUsage]
ON #DailyUsage (BU_ITEM_WID)
INCLUDE
(
TRANS_QTY,
GL_DT
);
WITH cte_ItemNums
AS (SELECT DISTINCT
IT.ITEM2_NUM,
IT.BU_ITEM_WID
FROM W_INVENTORY_TRANS_F IT
LEFT JOIN dbo.W_BU_ITEM_D BI
ON BI.BUSINESS_UNIT_WID = IT.BUSINESS_UNIT_WID
AND BI.ITEM_WID = IT.ITEM_WID
AND BI.STOCKING_TYPE = 'P'
WHERE 1 = 1
AND IT.DOCUMENT_TYPE_WID = 22
AND IT.BUSINESS_UNIT_WID = '837'
)
SELECT IT1.ITEM2_NUM,
COALESCE(SUM(IT2.TRANS_QTY), 0) AS 'Daily Usage',
D.Date AS 'Usage Date'
FROM #D AS D
LEFT OUTER JOIN cte_ItemNums IT1
ON 1 = 1
LEFT OUTER JOIN #DailyUsage IT2
ON IT2.GL_DT = D.Date
AND IT1.BU_ITEM_WID = IT2.BU_ITEM_WID
GROUP BY IT1.ITEM2_NUM,
D.Date;
【讨论】:
以上是关于不能缺少显示零的天数的主要内容,如果未能解决你的问题,请参考以下文章