Postgres:使用 group by 的结果作为列名

Tid*_*ddo 10 postgresql group-by

我在数据库中有一个消息表,其中包括发件人 ID 和消息类型(当然还有更多与此问题无关的列)。我尝试创建一个查询来计算用户发送的每种类型的消息数量。

例如,如果我有下表:

---------------------------
身份证 | 用户 ID | 消息类型
---------------------------
1 | 1 | 私人的
2 | 1 | 民众
3 | 1 | 私人的
---------------------------

然后我想得到以下内容:

---------------------
身份证 | 私人 | 民众
---------------------
1 | 2 | 1
---------------------

所以实际上我想按 message_type 和 user_id 分组,但不是为每个用户生成多行,我想创建多个列,每个 message_type 一个

我可以在不对查询中的消息类型进行硬编码的情况下实现这一点吗?

Tar*_*ryn 13

如果要转换为列的值数量有限,则可以使用带有CASE表达式的聚合函数轻松实现:

select user_id,
  sum(case when message_type = 'private' then 1 else 0 end) private,
  sum(case when message_type = 'public' then 1 else 0 end) public
from yourtable
group by user_id
Run Code Online (Sandbox Code Playgroud)

参见SQL Fiddle with Demo

PostgreSQL 有能力使用一个crosstab()可以通过安装tablefunc模块来使用的。这将执行从行到列的类似数据转换。创建查询的动态版本不是一个简单的过程,这里是StackOverflow 上动态交叉表的一个很好的解决方案。