0

我对以下代码有疑问:

    SELECT PM.PM_Eng_Name, ISNULL(SUM(PMOutput.Quantity),0) AS TotalOut
FROM PM LEFT OUTER JOIN
PMOutput ON PM.PM_code = PMOutput.PM_code
WHERE (PMOutput.Output_Date BETWEEN ‘2013-01-01’ AND ‘2013-08-25’)
GROUP BY PM.PM_Eng_Name  

当我运行这个查询时,我只获得了在所选日期范围内有输出交易的材料的总输出,而我需要为我拥有的所有 PM_Eng_Names 生成总输出,没有输出的材料的值为 0选定日期范围内的交易注意:当我删除 WHERE 子句时,我得到了完美的报告,但日期对我的项目很重要有人可以帮助我吗?

4

3 回答 3

4

要获得正确的结果,请将日期条件添加到join而不是whereisnull放入sum

select
    PM.PM_Eng_Name,
    sum(isnull(PMOutput.Quantity, 0)) as TotalOut
from PM
    left outer join PMOutput on PM.PM_code = PMOutput.PM_code and PMOutput.Output_Date BETWEEN ‘2013-01-01’ AND ‘2013-08-25’
group by PM.PM_Eng_Name
于 2013-08-25T11:20:36.267 回答
1

我认为这是因为来自的“外部连接”列PMOutput仅包含 null,因此它们被 where 子句过滤

会发生什么:

WHERE PMOutput.Output_Date is null or (PMOutput.Output_Date BETWEEN ‘2013-01-01’ AND ‘2013-08-25’) 
于 2013-08-25T11:16:21.497 回答
0

FROM是初始逻辑查询阶段之一,在WHERE应用之前完成。在WHERE您的查询中应用时,它会过滤掉很多行,因为它们的 Output_Date 是null.

所以最初你的 LEFT JOIN 这样做:

CREATE TABLE #j 
    (
    Name char(8)
    );
GO
INSERT INTO #j 
    values 
    ('jim'),
    ('michael'),
    ('raj'),
    ('jason'),
    ('tim');
GO

CREATE TABLE #q 
    (
    name char(8), 
    dateBirth datetime
    );
GO
INSERT INTO #q
    values 
    ('jim', '01 jan 2010'),
    ('michael', '01 sep 2010');
GO

SELECT * FROM #j LEFT OUTER JOIN #q ON #j.Name = #q.Name;

这将返回以下内容:

在此处输入图像描述

SQL-serverNULL根据它在查询的哪个阶段找到空值以及将哪个运算符应用于空值而进行不同的处理。在WHEREcluse 中,我们可以看到如果我们在此属性上指定过滤器,它会丢弃具有 null DateBirth 的行:

SELECT  *
FROM    #j
        LEFT OUTER JOIN #q ON
        #j.Name = #q.Name
WHERE   dateBirth BETWEEN '2000-01-01' AND '2020-01-01';

结果是:

在此处输入图像描述

(“逻辑查询阶段”将是一个很好的谷歌)

于 2013-08-25T17:02:03.147 回答