【问题标题】:Count over Partition by with one condition (/don't count the NULL values)用一个条件计算分区(/不计算 NULL 值)
【发布时间】:2019-08-23 11:29:44
【问题描述】:

我想计算一栋楼里有多少房子。数据集如下:

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

有什么建议吗?

【问题讨论】:

    标签: sql sql-server tsql sql-server-2012 analytic-functions


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      您可以简单地使用 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
      

      【讨论】:

        【解决方案3】:

        您可以检查以下自我加入选项-

        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 
        

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

            猜你喜欢
            • 2021-06-21
            • 1970-01-01
            • 1970-01-01
            • 2021-03-22
            • 2015-05-03
            • 2021-05-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多