在SQL中选择2个日期之间的数据

时间:2013-08-25 11:03:13

标签: sql sql-server

我遇到以下代码的问题:

    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子句时,我得到了完美的报告,但日期对我的项目很重要 有人可以帮我吗?

3 个答案:

答案 0 :(得分:4)

要获得正确的结果,请将日期条件添加到join而不是where,并将isnull添加到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

答案 1 :(得分:1)

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

会发生什么:

WHERE PMOutput.Output_Date is null or (PMOutput.Output_Date BETWEEN ‘2013-01-01’ AND ‘2013-08-25’) 

答案 2 :(得分: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 * 来自#j         LEFT OUTER JOIN #q ON           #j.Name =#q.Name;

返回以下内容:

enter image description here

SQL-server以不同的方式处理NULL,具体取决于查询的哪个阶段找到空值以及哪个运算符应用于空值。在WHERE cluse中,如果我们在此属性上指定过滤器,我们可以看到它丢弃具有null DateBirth的行:

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

结果:

enter image description here

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