不能缺少显示零的天数

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;

【讨论】:

以上是关于不能缺少显示零的天数的主要内容,如果未能解决你的问题,请参考以下文章

笔记本电脑缺少cloud.dll怎么办

天然气调用支付缺少参数怎么解决

缺少事件查看器说明

在 laravel 中获得总预订量为零的天数

firebase 错误:FirebaseError:缺少权限或权限不足

重新生成配置文件并不能解决缺少的权利