我如何只计算活动行而不是软删除

时间:2012-03-14 13:34:15

标签: sql sql-server

我有3个表,我想计算所有活动的串行资产。

我需要显示Serialized Inventory行,但可能没有将详细信息添加到SerialAssets表中,因此这给了我NULL行。 这样工作很好......

SELECT inv.Id AS Id, COUNT(s.Id) AS Total, MIN(i.Name) AS Asset
FROM SerialAssets AS s
RIGHT JOIN Inventories AS inv ON s.InventoryId = inv.Id
INNER JOIN Items AS i ON inv.ItemId = i.Id
WHERE i.Serialised = 1
GROUP BY inv.Id

但是现在我添加了软删除我只需要计算活动的SerialAssets,所以在WHERE中添加AND s.Active = 1可以正常工作,但它会删除通常显示为0的空值行。显然因为如果s .Active为null未选中,有没有办法更改计数或使s.active = 1或null?

更新

解决方案:

Damien_The_Unbeliever &安培; 的利芬

感谢您的快速回复!

5 个答案:

答案 0 :(得分:3)

AND s.Active = 1添加到 join 条件中,而不是添加到where子句中:

SELECT inv.Id AS Id, COUNT(s.Id) AS Total, MIN(i.Name) AS Asset
FROM SerialAssets AS s
RIGHT JOIN Inventories AS inv ON s.InventoryId = inv.Id
         AND s.Active = 1
INNER JOIN Items AS i ON inv.ItemId = i.Id
WHERE i.Serialised = 1
GROUP BY inv.Id

到(逻辑上)评估WHERE子句时,它并不关心结果集中每列的来源是什么 - 它关心的是评估那些条件中的值的条件列。如果这些列包含NULL,则它不知道是否因为该列在基表中包含NULL,或者它是外部JOIN不成功的结果。

答案 1 :(得分:1)

如果“活动”始终为1,0或null,则只能SUM处于活动状态。

更通用的解决方案看起来像这样

SUM(CASE
        WHEN /*insert active condition here*/ THEN 1
        ELSE 0
    END) AS ActiveCount

答案 2 :(得分:1)

s.Active= 1更改为

  • ISNULL(s.Active, 1) = 1
  • COALESCE(s.Active, 1) = 1

ISNULL

  

用指定的替换值替换NULL。

COALESCE

  

返回其参数中的第一个非空表达式。

答案 3 :(得分:0)

我可能没有遇到问题...但你是否试图计算所有s.Id等于1而不过滤查询返回的行?

如果是这种情况:

count(s.Id)替换为count(case when s.Id = 1 then 1 end)

答案 4 :(得分:0)

试试这个:

    SELECT inv.Id AS Id, 
            SUM(CASE WHEN COALESCE(s.ACtive, 1) = 1 THEN 1 ELSE 0 END) AS Total, 
            MIN(i.Name) AS Asset
    FROM Inventories AS inv
            INNER JOIN Items AS i ON inv.ItemId = i.Id
            LEFT OUTER JOIN SerialAssets AS s ON 
                    inv.Id = s.InventoryId
    WHERE i.Serialised = 1
    GROUP BY inv.Id

我重新安排了您的查询。最好使用LEFT OUTER JOIN代替。通过LEFT JOIN,人们更容易理解并且SQL Server的执行速度更快。