计算一列中的所有行,并在结果上得到 2 个不同的计数列,即使没有要计算的记录

Count all rows from a column, and get 2 different count columns on the result even if there are not records to count

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

问题是我需要在结果上显示 0,即使没有要计数的记录。

例如,我有这个 table subcategory 和这个示例数据:

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

我有这个 table 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    |*

请注意,产品 table 上没有与 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

使用 Left Joinsubcategory table 中获取所有行,然后执行 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,case语句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

只是另一种方式。

--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
)