sql - 将条件计数分段到相同的 'virtual' 列

标签 sql postgresql subquery

我正在尝试从这样的结果集中出发:

"foo" | "bar" | "baz"
----------------------
 30.0 |  20.0 | 50.0

(其中“foo”、“bar”和“baz”是各种条件 count() 语句的别名)

这样的结果集:

"segment" | "count"
-------------------
  "foo"   |   30.0
  "bar"   |   20.0
  "baz"   |   50.0

这是我的原始查询:

SELECT round(count(CASE WHEN posts.deactivated_for IS NULL THEN 1 END) ::DECIMAL / count(*), 4) * 100 AS "Foo",
       round(count(CASE WHEN posts.deactivated_for ILIKE '%Died%' THEN 1 END) ::DECIMAL / count(*), 4) * 100 AS "Bar",
       round(count(CASE WHEN posts.deactivated_for ILIKE '%(#%' THEN 1 END) ::DECIMAL / count(*), 4) * 100 AS "Baz"
FROM posts

感谢您的帮助。

最佳答案

您可以使用横向连接:

SELECT v.*
FROM (SELECT round(count(CASE WHEN posts.deactivated_for IS NULL THEN 1 END) ::DECIMAL / count(*), 4) * 100 AS "Foo",
             round(count(CASE WHEN posts.deactivated_for ILIKE '%Died%' THEN 1 END) ::DECIMAL / count(*), 4) * 100 AS "Bar",
             round(count(CASE WHEN posts.deactivated_for ILIKE '%(#%' THEN 1 END) ::DECIMAL / count(*), 4) * 100 AS "Baz"
      FROM posts
     ) p, lateral
     (VALUES ('Foo', "Foo"), ('Bar', "Bar"), ('Baz', "Baz")) v(segment, cnt);

或者,如果组是离散的,您可以只使用group by:

SELECT (CASE WHEN p.deactivated_for IS NULL THEN 'Foo'
             WHEN p.deactivated_for ILIKE '%Died%' THEN 'Bar'
             WHEN p.deactivated_for ILIKE '%(#%' THEN 'Baz'
        END) as segment,
        COUNT(*) * 100.0 / SUM(COUNT(*)) OVER ()
FROM posts p
GROUP BY segment
HAVING segment IS NOT NULL;

关于sql - 将条件计数分段到相同的 'virtual' 列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46920165/

相关文章:

sql - 从数据集 SQL 创建趋势线

sql - 无法计算用于较大 PostgreSQL 查询输出列的 CTE 子查询输出之间的差异

java - 检查密码是否与特定用户匹配 - PostgreSQL 和 Java

java - 使用 PostgreSQL 获取索引值

database - 如何在一个查询中切换 postgres 中的 boolean 值

mysql - SELECT 子句中的子查询

php - 如何过滤复杂 SQL 查询的结果?

SQL:查找所有 parent 与我相似的 child

sql - 在多个条件下返回左外连接中的最后一行

mysql - 为什么这个语句在作为子查询的一部分时有效?