我有一个包含许多不同产品的大型数据集.在小范围内,它看起来像这样:

product month amount
AA 1 100
AA 1 150
AA 2 200
AA 2 120
BB 2 180
BB 2 220
CC 3 80

我想以不同的顺序得到信息.在"产品"列中写入尽可能多的新列,然后填写每月的金额总和.它看起来像这样:

month AA BB CC
1 250 NA NA
2 320 400 NA
3 NA NA 80

重要的是旋转工作表,这是我的主要问题.我看到了类似的问题,但都已经用Pivot函数解决了,但我使用的是DBeaver中的Postgres数据库,它没有Pivot函数:

SELECT *
FROM (
    SELECT product, month, amount
    FROM ventas
) AS SourceTable
PIVOT (
    SUM(amount)
    FOR month IN ([1], [2], [3])
) AS PivotTable;

SQL错误[42601]:错误:语法错误在或附近"PIVOT" 职位:95

我试过不同的方法,但没有成功.I can't write the names of all products in the query as there are too many!

以下是一个测试设置,以方便您:

CREATE TABLE ventas (
    product VARCHAR(50),
    month INT,
    amount INT
);

INSERT INTO ventas (product, month, amount) VALUES 
('AA', 1, 100),
('AA', 1, 150),
('AA', 2, 200),
('AA', 2, 120),
('BB', 2, 180),
('BB', 2, 220),
('CC', 3, 80),

推荐答案

如果您实际上需要单独的输出列,唯一合理的方法是两步流程:

  1. 动态生成查询.
  2. 执行它.

如果您不熟悉crosstab()功能,请先阅读以下内容:

-- generate crosstab() query
SELECT format(
$f$  -- begin dynamic query string
SELECT * FROM crosstab(
   $q$
   SELECT month, product, sum(amount)
   FROM   ventas
   GROUP  BY 1, 2
   ORDER  BY 1, 2
   $q$
 , $c$VALUES (%s)$c$
   ) AS ct(month int, %s);
$f$  -- end dynamic query string
            , string_agg(quote_literal(sub.product), '), (')
            , string_agg(quote_ident  (sub.product), ' int, ') || ' int'
                 )
FROM  (SELECT DISTINCT product FROM ventas ORDER BY 1) sub;

这将生成一个表单的查询:

SELECT * FROM crosstab(
   $q$
   SELECT month, product, sum(amount)
   FROM   ventas
   GROUP  BY 1, 2
   ORDER  BY 1, 2
   $q$
 , $c$VALUES ('AA'), ('BB'), ('CC')$c$
   ) AS ct(month int, "AA" int, "BB" int, "CC" int);

...然后由你来执行.

fiddle

密切相关,有更多解释和 Select :

Sql相关问答推荐

使用SQL/R循环查找邻居

SUM(条件)在Oracle?

删除MariaDB数据库中的JSON数据

在请求结束之前,PostgreSQL不会考虑使用中的删除

在Postgres中实现合并功能的干净方法,因为当目标/源不匹配时

UPDATE查询中的乐观锁

PostgreSQL 9.6嵌套的INSERT/RETURN语句的CTE性能低得令人无法接受

查询每周数据(周一至周日),避免年度日期重叠

在MS Access Modern图表的X轴上显示时间值时遇到问题

Oracle 23c ROUND,数据类型为DATE

对于多字节字符,SQL Server中的DATALENGTH返回1字节

如何根据几个条件 Select 值:如果满足一个范围的SUM,则对另一个范围求和

根据标识符将两行合并为一行

使用 Oracle SQL Developer 将不同的列值转换为列会导致错误 ORA-01489

使用 union 的有序结果获取行数

GRAFANA 数据库查询错误:pq:列名称不存在

SQL 查询是否返回列表中仅包含某些值而不包含其他值的行?

带聚合函数的 percentile_cont

连续期间的缺口

BigQuery 错误:SELECT 列表表达式引用 esthetician.LICENSE_TYPE,它既未在 [49:8] 分组也未聚合