postgresql - Postgres - 按年份绑定(bind)相同类型的结果 - 从长到宽数据

标签 postgresql pivot-table

请原谅我不太恰当的提问方式,因为我是 postgres 的新手...

有如下两个表:

CREATE TABLE pub (
   id int
 , time timestamp
);

     id                time
1     1 2010-02-10 01:00:00
2     2 2011-02-10 01:00:00
3     3 2012-02-10 01:00:00

CREATE TABLE val (
   id int
 , type text
 , val int
);

     id  type   val
1     1     A     1
2     1     B     2
3     1     C     3
4     2     A     4
5     2     B     5
6     3     D     6

我想获得以下输出(对于 id <= 2 )

   type   2010   2011
1     A      1      4
2     B      2      5
3     C      3   NULL

所以 type是表 val 中存在的所有类型的超集。
NULL 表示标签 C 没有值。
理想情况下,列标题是时间的年份。或者 id 本身......

最佳答案

至少有两种方法可以做到这一点。

如果你的表格没有太多类别你可以使用 CTE

WITH x AS (
    SELECT type,
           sum(val) FILTER (WHERE date_part('year', time) = 2010) AS "2010",
           sum(val) FILTER (WHERE date_part('year', time) = 2011) AS "2011"
    FROM pub AS p JOIN val AS v ON (v.id = p.id)
    GROUP BY type
) 
SELECT * FROM x
WHERE "2010" is NOT NULL OR "2011" IS NOT NULL
ORDER BY type
;

但是如果你有很多或动态的类别,你必须使用交叉表:

CREATE EXTENSION tablefunc;

SELECT * FROM crosstab(
     $$
         SELECT type,
                date_part('year', time)::text as time,
                sum(val) AS val
           FROM pub AS p JOIN val AS v ON (v.id = p.id)
       GROUP BY type, 2 
       ORDER BY 1, 2
     $$,
     $$VALUES ('2010'::text), ('2011'), ('2012') $$
     ) AS ct (type text, "2010" int, "2011" int, "2012" int);
;

关于postgresql - Postgres - 按年份绑定(bind)相同类型的结果 - 从长到宽数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42149376/

相关文章:

c# - 获取错误没有函数匹配给定的名称和参数类型。您可能需要添加显式类型转换。”

mysql - 如何将状态列中的内容显示为数据库中的标题

postgresql - 如何将值从更改的行发送到 postgres 中的触发器?

postgresql - 如何将 pg_dump 文件恢复到 postgres 数据库中

node.js - 提交对迁移命令的新更改 - sequelize-cli Nodejs

c# - Hangfire:打开的连接太多

excel - 立方体场?在数据透视表上设置过滤器值

python - Pandas 数据 reshape ,根据关联将具有相同索引但不同值的多行转换为多列

python - Pandas 数据框单元格中的嵌套列表,如何提取?

SQL Server 多枢轴