计算列中的所有行,并在结果上获得2个不同的计数列,即使没有要计数的记录也是如此

时间:2015-01-04 18:32:41

标签: sql-server

我想要做的是计算列State中的所有行,并在结果上获得2个不同的计数列(每个可能的值为1或0)。

即使没有可记录的记录,我还是需要在结果0上显示。

例如,我将此表subcategory包含此示例数据:

  SubcategoryID |   Name    |
  ---------------------------
        201     |   Name1   |
        202     |   Name2   |
        203     |   Name3   |
        204     |   Name4   |

我有这个表product和这个样本数据:

  ProductID |Subcategory| State |
  -------------------------------
    101     |   201     |   1   |
    102     |   201     |   1   |
    103     |   201     |   1   |
    104     |   202     |   0   |
    105     |   202     |   0   |
    106     |   203     |   1   |
    107     |   203     |   0   |
    108     |   203     |   0   |

状态:1 =有效,0 =无效

所以我想得到这个:

|Subcategory| Active|Inactive|
------------------------------
|   201     |   3   |   0    |
|   202     |   0   |   2    |
|   203     |   1   |   2    |
|   204     |   0   |   0    |*

请注意,产品表中没有与SubcategoryId = 204相关的产品。

我正在使用此查询来仅获取与一个子类别相关的产品。你知道我要添加什么来获得“| 204 | 0 | 0 |”这一行吗? ?

select p.subcategory,
       sum(case when state = 1 then 1 else 0 end) as active,
       sum(case when state = 0 then 1 else 0 end) as inactive
from product p
group by p.subcategory

2 个答案:

答案 0 :(得分:5)

使用Left Join获取subcategory表中的所有行,然后执行Count

SELECT S.subcategoryID,
       Sum(CASE WHEN state = 1 THEN 1 ELSE 0 END) AS active,
       Sum(CASE WHEN state = 0 THEN 1 ELSE 0 END) AS inactive
FROM   subcategory s
       LEFT JOIN product p
              ON s.SubcategoryID = p.Subcategory
GROUP  BY s.subcategoryID 

或者使用Count,可以避免案例陈述else部分

SELECT S.subcategoryID,
       count(CASE WHEN state = 1 THEN 1 END) AS active,
       count(CASE WHEN state = 0 THEN 1 END) AS inactive
FROM   subcategory s
       LEFT JOIN product p
              ON s.SubcategoryID = p.Subcategory
GROUP  BY s.subcategoryID 

SQLFIDDLE DEMO

答案 1 :(得分:0)

另一种方法。

--Getting the counts for 'active' and 'inactive' states
SELECT S.subcategoryID,
       count(CASE WHEN state = 1 THEN 1 END) AS active,
       count(CASE WHEN state = 0 THEN 1 END) AS inactive
FROM   subcategory s
       JOIN product P ON s.SubcategoryID = p.Subcategory
GROUP  BY s.subcategoryID 

--Now adding subcategories which are only in subcategory table using `EXCEPT`.
UNION ALL
(
SELECT subcategoryid, 0, 0 from subcategory
EXCEPT
SELECT subcategory, 0, 0 from product
)