【问题标题】:Calculating Percentage of Various Categories that Meet Conditions with SQL Server使用 SQL Server 计算满足条件的各种类别的百分比
【发布时间】:2019-02-04 02:40:33
【问题描述】:

我有一张表格,其中包含有关城市之间航班的信息,如下所示:

    origin_city dest_city   time    
    Dothan AL   Atlanta GA    171    
    Dothan AL   Atlanta GA    171    
    Dothan AL   Elsewhere AL    2    
    Dothan AL   Elsewhere AL    2    
    Dothan AL   Elsewhere AL    2    
    Boston MA   New York NY     5    
    Boston MA   City MA         1    
    New York NY Boston MA       5    
    New York NY Boston MA       5    
    New York NY Boston MA       5    
    New York NY Poughkipsie NY  2

我想查找每个始发城市的飞行时间少于 3 小时的航班的百分比。所以结果会是这样的:

    Dothan AL    60
    Boston MA    50
    New York NY  25

我认为可行的代码如下所示:

     SELECT F.origin_city as origin_city,    
       ((SELECT COUNT(*) FROM Flights as F2
       WHERE F2.actual_time < 3) / (SELECT COUNT(*) FROM Flights as  F3)) * 100
     AS percentage
     FROM Flights as F
     GROUP BY F.origin_city
     ORDER BY percentage;
     GO

当我运行它时,我得到了一个起始城市列表和一个百分比列,正如预期的那样,但百分比始终为 0。我仍然对子查询很困惑(如你所见)。

【问题讨论】:

    标签: sql sql-server subquery correlated-subquery


    【解决方案1】:

    我会使用AVG() 作为窗口函数来做到这一点:

    SELECT F.origin_city as origin_city, 
           AVG( CASE WHEN F2.actual_time < 3 THEN 100.0 ELSE 0 END) as percentage
    FROM Flights F
    GROUP BY F.origin_city
    ORDER BY percentage;
    

    这假定时间以小时为单位。根据谷歌地图,你可以在 68 小时内从多森步行到亚特兰大,所以 171 很可疑。

    【讨论】:

      【解决方案2】:

      您的百分比是针对整个表格的,而不是按始发城市分组的。试试这样的:

       SELECT F.origin_city as origin_city,    
         (SUM(CASE WHEN F.actual_time < 3 THEN 1 ELSE 0 END) / COUNT(*) )  * 100 AS percentage
       FROM Flights as F
       GROUP BY F.origin_city
       ORDER BY percentage;
       GO
      

      FWIW 您当前子查询的问题是您当前行和子查询中的数据之间没有连接。您可能可以将其重写为:

       SELECT F.origin_city as origin_city,    
       ((SELECT COUNT(*) FROM Flights as F2
       WHERE F2.origin_city = F.origin_city and F2.actual_time < 3) / (SELECT COUNT(*) FROM Flights as  F3 where F3.origin_city = F.origin_city)) * 100
       AS percentage
       FROM Flights as F
       GROUP BY F.origin_city
       ORDER BY percentage;
       GO
      

      但是当您已经有足够的数据来进行如上所示的计算时,没有必要为每一行重新查询表。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-16
        • 1970-01-01
        相关资源
        最近更新 更多