即使存在值,SQL Server CASE也会返回NULL

时间:2015-10-02 06:06:05

标签: sql sql-server null case-when

以下是我的示例查询。当我运行查询时,即使存在日期范围内的数据,PreviousTotalQuantity也会返回null。

SELECT
    p.ActualId,
    p.Name,
    p.QTYONHAND AS OnHand,
    p.PRICE AS DistCost,
    SUM(soi.Quantity) AS PresentTotal,
    SUM(CASE
        WHEN soi.MASSCHDSHIPDATE > '2014-3-1' AND
            soi.MASSCHDSHIPDATE < '2014-6-1' THEN soi.Quantity
        ELSE NULL
    END) AS PreviousTotalQuantity
FROM 
    sysdba.PRODUCT p
    LEFT OUTER JOIN sysdba.SALESORDERITEMS soi
        ON p.PRODUCTID = soi.PRODUCTID
WHERE 
    soi.MASSCHDSHIPDATE > '2015-3-1' AND 
    soi.MASSCHDSHIPDATE < '2015-6-1'
GROUP BY p.PRODUCTID, p.ACTUALID, p.NAME, p.QTYONHAND, p.PRICE

我还需要在给定日期提取上一年的数据。

3 个答案:

答案 0 :(得分:0)

因为您的年份在select(2014)和where(2015)part

中不同步

修改

SELECT
    p.ActualId,
    p.Name,
    p.QTYONHAND AS OnHand,
    p.PRICE AS DistCost,
    SUM(soi.Quantity) AS PresentTotal,
    ISNULL(prev.TotalQty, 0) AS PreviousTotalQuantity
FROM 
    sysdba.PRODUCT p
    LEFT OUTER JOIN sysdba.SALESORDERITEMS soi
        ON p.PRODUCTID = soi.PRODUCTID
    OUTER APPLY
    (
        SELECT SUM(Quantity) AS TotalQty 
        FROM sysdba.SALESORDERITEMS 
        WHERE PRODUCTID = p.PRODUCTID 
            AND MASSCHDSHIPDATE > '2014-03-01' AND MASSCHDSHIPDATE < '2014-06-01'
    ) AS prev
WHERE 
    soi.MASSCHDSHIPDATE > '2015-03-01' AND 
    soi.MASSCHDSHIPDATE < '2015-06-01'
GROUP BY p.PRODUCTID, p.ACTUALID, p.NAME, p.QTYONHAND, p.PRICE, prev.TotalQty

答案 1 :(得分:0)

不要手动比较日期。

子句之间使用

Declare @PRODUCT table
(
Name varchar(50),
Date datetime,
Quantity int
)

INSERT INTO @PRODUCT VALUES ('Nikunj','2014-3-1',20)
INSERT INTO @PRODUCT VALUES ('Nikunj','2014-6-1',40)
INSERT INTO @PRODUCT VALUES ('Nikunj','2014-9-1',60)
INSERT INTO @PRODUCT VALUES ('JayDeep','2014-3-1',10)
INSERT INTO @PRODUCT VALUES ('JayDeep','2014-9-1',20)

select Name, sum(Quantity),SUM(Case when Date between '2014-3-1' and '2014-6-1' then Quantity else NULL end) TotalQuantity from @PRODUCT 
where Date between '2014-3-1' and '2014-6-1' group by Name 

相应地尝试这一点,并在where条件代码中检查

答案 2 :(得分:0)

这里的问题是你在WHERE语句中限制了2015年的行,因此在2014年的结果集中没有行。所以你因为CASE在AFTER WHERE语句中起作用而得到NULL。

如果您需要选择当前的2015年并计算2014年的此字段,则可以使用此查询。我不知道PRODUCTID在sysdba.PRODUCT中是否是唯一的,所以我使用带有DISTINCT的子查询。如果这些字段在产品中是唯一的,则只需使用FROM PRODUCTS P而不使用DISTINCT子查询:

SELECT
    p.ActualId,
    p.Name,
    p.QTYONHAND AS OnHand,
    p.PRICE AS DistCost,
    soi2015.SUM_Quantity AS PresentTotal,
    soi2014.SUM_Quantity AS PreviousTotalQuantity
FROM 
    (SELECT  DISTINCT 
             p.ActualId,
             p.Name,
             p.QTYONHAND AS OnHand,
             p.PRICE AS DistCost,        
             FROM sysdba.PRODUCT 
    ) p 
    LEFT OUTER JOIN 
      (SELECT PRODUCTID,SUM(soi.Quantity)  SUM_Quantity
        FROM  sysdba.SALESORDERITEMS
        WHERE (MASSCHDSHIPDATE > '2015-03-01') 
               AND (MASSCHDSHIPDATE < '2015-06-1')
        GROUP BY PRODUCTID
      ) soi2015 ON (p.PRODUCTID = soi2015.PRODUCTID) 
    LEFT OUTER JOIN 
      (SELECT PRODUCTID,SUM(soi.Quantity)  SUM_Quantity
        FROM  sysdba.SALESORDERITEMS
        WHERE (MASSCHDSHIPDATE > '2014-03-01') 
               AND (MASSCHDSHIPDATE < '2014-06-1')
        GROUP BY PRODUCTID
      ) soi2014 ON (p.PRODUCTID = soi2014.PRODUCTID)