在一个条件下对 Partition by 进行计数(/不计算 NULL 值)

Count over Partition by with one condition (/don't count the NULL values)

我想数一数建筑物内有多少间房屋。数据集如下:

BuildingID, HouseID
1, 1
1, 2
1, 3
2, 4
2, 5
2, 6
NULL, 7
NULL, 8

下面的代码显示了房子的总数,但是,房子 7 和 8 没有建筑物,所以它不应该计算任何东西。

SELECT BuildingID
     , HouseID
     , COUNT(HouseID) OVER (PARTITION BY BuildingID) AS 'Houses in Building'
FROM BUILDING

我得到的结果:

BuildingID, HouseID, Houses in Building
1, 1, 3
1, 2, 3
1, 3, 3
2, 4, 3
2, 5, 3
2, 6, 3
NULL, 7, 2
NULL, 8, 2

我想要的结果:

BuildingID, HouseID, Houses in Building
1, 1, 3
1, 2, 3
1, 3, 3
2, 4, 3
2, 5, 3
2, 6, 3
NULL, 7, NULL --or 0
NULL, 8, NULL --or 0

有什么建议吗?

算一下BuildingID。 COUNT 函数不计算空值,因此它可以工作:

COUNT(BuildingID) OVER (PARTITION BY BuildingID) AS 'Houses in Building'

请注意,它假定 HouseID 不为空。

您可以简单地使用 case 表达式仅显示 BuildingID 不为空的计数,或者您可以将计数更改为 COUNT(BuildingID) 而不是 COUNT(HouseID)(因为 COUNT(NULL) 给出 0)。两者都会产生您需要的结果:

DECLARE @Building TABLE (BuildingID INT, HouseID INT);
INSERT @Building (BuildingID, HouseID)
VALUES 
    (1, 1), (1, 2), (1, 3), (2, 4), (2, 5), 
    (2, 6), (NULL, 7), (NULL, 8);

SELECT  BuildingID,
        HouseID,
        CountBuildingID = COUNT(BuildingID) OVER (PARTITION BY BuildingID),
        CaseExpression = CASE WHEN BuildingID IS NOT NULL THEN COUNT(HouseID) OVER (PARTITION BY BuildingID) END
FROM    @Building
ORDER BY HouseID;

输出

BuildingID   HouseID    CountBuildingID     CaseExpression
-------------------------------------------------------
1               1           3                   3
1               2           3                   3
1               3           3                   3
2               4           3                   3
2               5           3                   3
2               6           3                   3
NULL            7           0                   NULL
NULL            8           0                   NULL

您可以检查以下自连接选项-

WITH your_table (BuildingID, HouseID)
AS
(
SELECT 1, 1 UNION ALL
SELECT 1, 2 UNION ALL
SELECT 1, 3 UNION ALL
SELECT 2, 4 UNION ALL
SELECT 2, 5 UNION ALL
SELECT 2, 6 UNION ALL
SELECT NULL, 7 UNION ALL
SELECT NULL, 8
)

SELECT A.BuildingID,A.HouseID,COUNT(A.BuildingID)Count
FROM your_table A
LEFT JOIN your_table B ON A.BuildingID = B.BuildingID
GROUP BY A.BuildingID,A.HouseID

输出是-

BuildingID  HouseID Count
1           1       3
1           2       3
1           3       3
2           4       3
2           5       3
2           6       3
NULL        7       0
NULL        8       0 

您可以在 Count 函数中使用 case when 条件,如下所示,

COUNT(CASE WHEN BuildingID IS  NOT NULL THEN HouseID END) OVER (PARTITION BY BuildingID)  AS 'Houses in Building'