sql - 如何使用重复的 WHERE 子句和 LEFT JOINS 使查询更动态(无 crostab)

标签 sql postgresql

编辑:我使用的是不支持 crostab 的旧版 Postgresql。

我有一个查询,我正试图通过更容易地为一个旨在为单个用户汇总信息的表添加新值来改进

每次我向下面称为算法的这一列添加一个值时,我基本上都必须编写一个新的左连接和 where 子句:

┌───────────────────────────────┐
│          algo                 │
├───────────────────────────────┤
│ Algorithm1                    │
│ Algorithm2                    │
│ Algorithm3                    │
└───────────────────────────────┘

这是我为生成输出而编写的查询:

select a.userid, a.algo, a.algo1_cnt, b.algo, b.algo2t_cnt, c.algo, c.algo3_cnt
    from
    (select userid, algo, count(*) as algo1_cnt
    from test_table
    where (algo = 'Algorithm1')
    group by 1,2 ) as a
    LEFT OUTER JOIN
    ( select userid, algo, count(*) as algo2_cnt
    from test_table
    where (algo = 'Algorithm2')
    group by 1,2 ) as b
    ON
    (a.userid = b.userid)
    LEFT OUTER JOIN
    ( select userid, algo, count(*) as algo3_cnt
    from test_table
    where (algo = 'Algorithm3')
    group by 1,2 ) as c
    ON
    (a.userid = c.userid)

查询的输出现在如下所示:

┌──────────────────────┬────────────────┬───────────┬───────┬───────────┬───────────────────────────────┬───────────┐
│        userid        │     algo1      │ algo1_cnt │ algo2 │ algo2_cnt │             algo3             │ algo3_cnt │
├──────────────────────┼────────────────┼───────────┼───────┼───────────┼───────────────────────────────┼───────────┤
│ user1                │ algo1          │         3 │       │           │ algo3                         │         2 │
│ user2                │ algo1          │         2 │       │           │                               │           │

Question: What is the best way to modify the query to be able to read the distinct values from the algo column in a dynamic fashion and generate the same outpuy?

我的意思是,如果我向算法列添加一个名为 Algorithm4 的新值,我可以利用 PL/PGSQL 或其他一些动态递归来生成相同的输出而不必使用 WHERE (algo = 'Algorithm4') 吗?

最佳答案

您可以使用 crosstab但是如果你可以在其他地方拆分数组,那么这就简单多了

select 
    user_id, 
    array_agg(algo) as algo, 
    array_agg(algo_count) as algo_count
from (
    select userid, algo, count(*) as algo_count
    from test_table
    group by 1, 2
) s
group by 1

JSON 爱好者也可以拥有它

select
    user_id,
    format(
        '{%s}',
        string_agg(format('"%s": %s', algo, algo_count), ', ')
    )::json as algo_obj
from (
    select userid, algo, count(*) as algo_count
    from test_table
    group by 1, 2
) s
group by 1

关于sql - 如何使用重复的 WHERE 子句和 LEFT JOINS 使查询更动态(无 crostab),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24335115/

相关文章:

Mysql多对多表查询

sql - 使用 SQL*Plus 从以前的 SELECT 中选择总计

java - 从 java.time.MonthDay 到 java.sql.* 的映射

sql - postgresql 每月创建天数表

postgresql - postgis 将点转换为多边形

sql - 如何关闭在数据库链接 (ORA-02080) 中创建的游标?

java - Hibernate Result Transformer 无法实例化 resultclass

Postgresql 9.1 从所有模式中选择

postgresql - Postgres 分层 (jsonb) CTE 不必要地慢

postgresql - PostgreSQL从声明的表中插入(存储过程或函数)