【问题标题】:SQL syntax to SUM a Count column for calculating percentage distribution用于计算百分比分布的 SUM 计数列的 SQL 语法
【发布时间】:2015-04-06 11:11:34
【问题描述】:

我正在使用 SQL Server 2014,并且我有以下运行良好的查询:

USE MyDatabase

SELECT [Room Nights],
       COUNT([Room Nights]) AS 'Count of RN'
FROM HOLDINGS2
GROUP BY [Room Nights]

输出如下:

Room Nights      Count of RN
 1                 3
 4                 10
 5                 6
 7                 25

现在我想显示另一列,它给出了Count of RN 的百分比分布。因此,我的输出需要是这样的:

Room Nights      Count of RN    % Distribution
     1                 3           6.8
     4                 10          22.7
     5                 6           13.6
     7                 25          56.8

我查看了以下讨论以尝试找出解决方案: percent distribution with counted values.

我对现有代码进行了以下修改,但它不起作用!我在% Distribution 列中只有零。

USE MyDatabase

SELECT [Room Nights],
       COUNT([Room Nights]) AS 'Count of RN',
       CAST(COUNT([Room Nights])/(SELECT COUNT([Room Nights])*100. FROM HOLDINGS2) AS DECIMAL (9,0)) AS '% Distribution'
FROM HOLDINGS2
GROUP BY [Room Nights]

基本上,% Distribution 列应采用 Count of RN 并将其除以 TOTAL Count of RN

【问题讨论】:

    标签: sql sql-server count sql-server-2014


    【解决方案1】:

    这可行:

    select [Room Nights],
      count([Room Nights]) AS 'Count of RN',
      cast(
        (count([Room Nights])
        /
        (Select Count([Room Nights]) * 1.0 from HOLDINGS2) 
       ) * 100 as decimal(6,1)
      ) as '% Distribution'    
    FROM HOLDINGS2
    GROUP BY [Room Nights]
    

    子查询中的* 1.0 强制进行浮点除法,外部强制转换限制了精度。

    或者,当您使用现代版本的 MSSQL 时,您可以使用窗口函数:

    cast(count([Room Nights])/(sum(count([Room Nights])*1.0) over ()) * 100 as decimal(6,1))
    

    【讨论】:

    • 这个,或者为分子或分母添加一个内部转换。我将ughai的原始答案修改为 first 将计数转换为十进制 然后 将其除以总数,这很有效 - 但会给你很大的精度,所以你需要四舍五入或有外铸。
    • @jpw,只是一个小缺陷。您缺少 group by 子句
    • @GiorgiNakeuri 感谢您的关注,忘记复制了。
    【解决方案2】:

    试试:

    DECLARE @t TABLE
        (
          [Room Nights] INT ,
          [Count of RN] INT
        )
    
    INSERT  INTO @t
    VALUES  ( 1, 3 ),
            ( 4, 10 ),
            ( 5, 6 ),
            ( 7, 25 )
    
    
    SELECT  * ,
            ROUND([Count of RN] * 100.0
                  / SUM([Count of RN]) OVER ( ORDER BY ( SELECT NULL ) ), 1) AS [Percent]
    FROM    @t        
    

    输出:

    Room Nights Count of RN Percent
    1           3           6.800000000000
    4           10          22.700000000000
    5           6           13.600000000000
    7           25          56.800000000000
    

    编辑:我错过了 RN 计数是分组查询的结果。这是修改后的声明:

    SELECT  [RN] ,
            COUNT(S) AS C ,
            CAST(COUNT(S) * 100.0 / SUM(COUNT(S)) OVER () AS DECIMAL(10, 1)) AS [Percent]
    FROM    @t
    GROUP BY [RN]   
    

    【讨论】:

    • [Count of RN] 是查询的结果,而不是源的一部分。您当然可以将第一个查询作为 cte 或派生表运行。
    【解决方案3】:

    您可以使用窗口函数计算% Distribution,乘以100.0 以强制结果为float,然后在逗号后面保留最多1 位:

    select [Room Nights]
          , count([Room Nights]) as [Count of RN]
          , cast(100.0 * count([Room Nights])/(sum(count([Room Nights])) over ()) as decimal(6,1)) as [% Distribution]
    from HOLDINGS2
    group by [Room Nights]   
    

    SQLFiddle

    您也可以使用子查询:

    select [Room Nights]
         , count([Room Nights]) as [Count of RN]
         , cast(100.0 * count([Room Nights])/(select count([Room Nights]) from HOLDINGS2) as decimal(6,1)) as [% Distribution]
    from HOLDINGS2
    group by [Room Nights]  
    

    SQLFiddle

    【讨论】:

    • 您需要将分布转换为十进制或数字,以获得具有精度点的分布百分比。
    【解决方案4】:

    试试这样的

    select [Room Nights],
           count([Room Nights]) AS 'Count of RN',
           (CONVERT(DECIMAL(9,2),count([Room Nights]))/(Select Count([Room Nights]) from HOLDINGS2))*100 as '% Distribution'
    FROM HOLDINGS2
    GROUP BY [Room Nights]
    

    【讨论】:

    • 我认为你最后缺少一个括号。无论如何,它仍然在该列中给我零。
    • 我一开始就错过了。立即尝试。
    猜你喜欢
    • 1970-01-01
    • 2023-02-01
    • 2021-01-31
    • 1970-01-01
    • 2015-06-11
    • 2020-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多