sql - 在同一个 SELECT sql 查询中从 SUM() 计算百分比

标签 sql postgresql count aggregate-functions postgresql-9.1

在表 my_obj 中有两个整数字段:

(value_a integer, value_b integer);

我尝试计算 value_a = value_b 的次数,我想用百分比表示这个比率。 这是我试过的代码:

select sum(case when o.value_a = o.value_b then 1 else 0 end) as nb_ok,
       sum(case when o.value_a != o.value_b then 1 else 0 end) as nb_not_ok,
       compute_percent(nb_ok,nb_not_ok)
from  my_obj as o
group by o.property_name;

compute_percent 是一个简单地执行 (a * 100)/(a + b)

的存储过程

但是 PostgreSQL 提示列 nb_ok 不存在。
你会如何正确地做到这一点?

我在 Ubuntu 12.04 上使用 PostgreSQL 9.1。

最佳答案

这个问题比看起来要复杂得多。

简单版

更快更简单:

SELECT property_name
      ,(count(value_a = value_b OR NULL) * 100) / count(*) AS pct
FROM   my_obj
GROUP  BY 1;

结果:

property_name | pct
--------------+----
 prop_1       | 17
 prop_2       | 43

如何?

  • 你根本不需要这个函数。

  • 不是计算 value_b(您不需要从它开始)和计算总数,而是使用 count(*) 来计算总数。更快、更简单。

  • 假设您没有 NULL 值。 IE。两列都定义为 NOT NULL。您的问题中缺少信息。
    如果不是,则您的原始查询可能没有按照您的想法行事。如果任何值为 NULL,则您的版本根本不计算该行。您甚至可以通过这种方式引发被零除异常。
    此版本也适用于 NULL。 count(*) 生成所有行的计数,而不考虑值。

  • 计数的工作原理如下:

     TRUE  OR NULL = TRUE
     FALSE OR NULL = NULL
    

    count() 忽略 NULL 值。瞧。

  • Operator precedence控制 =OR 之前绑定(bind)。您可以添加括号以使其更清楚:

    count ((value_a = value_b) OR FALSE)
    
  • 你可以用

    做同样的事情
    count NULLIF(<expression>, FALSE)
    
  • count()的结果类型默认为bigint
    除法 bigint/bigint截断小数位

包括小数位

使用 100.0(带小数位)强制计算为数字,从而保留小数位。
您可能想使用 round()有了这个:

SELECT property_name
      ,round((count(value_a = value_b OR NULL) * 100.0) / count(*), 2) AS pct
FROM   my_obj
GROUP  BY 1;

结果:

property_name | pct
--------------+-------
 prop_1       | 17.23
 prop_2       | 43.09

顺便说一句:
我使用 value_a 而不是 valueA。不要在 PostgreSQL 中使用不带引号的混合大小写标识符。我已经看到太多来自这种愚蠢的绝望问题。如果您想知道我在说什么,请阅读本章 Identifiers and Key Words在手册中。

关于sql - 在同一个 SELECT sql 查询中从 SUM() 计算百分比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15644713/

相关文章:

sql - "Simple"SQL查询

MySQL删除并加入

postgresql - 如何从终端打开 Heroku PostgresQL 数据库(我需要命令)

postgresql - Dancer2 Auth::Extensible 不接受散列密码

java - 如何从一种方法获取 int 值到另一种方法

Python psycopg2 不在 utf-8 中

mysql - 连接 3 个表以获得单行

sql - 接收与主键数组匹配的记录,顺序与它们在数组中出现的顺序相同

python - 使用 list.count 搜索列表中的多个项目?

php - 获取具有特定值的字段数? :mysql-php