sql - 使用交叉表函数的 PostgreSQL 和数据透视表

标签 sql postgresql pivot crosstab

我在使用 crosstab() 函数在 PostgreSQL 中创建数据透视表时遇到问题。它运行良好,但它会为同一个 client_id 生成多个记录。我怎样才能避免这种情况?

这是 SQL:

SELECT *
FROM crosstab('SELECT client_id
                     ,extract(year from date)
                     ,sum(amount)
               from   orders
               group  by extract(year from date)
                     ,client_id'
             ,'SELECT extract(year from date)
               FROM   orders
               GROUP  BY extract(year from date)
               order  by extract(year from date)')
AS orders(
row_name integer,
year_2001 text,
year_2002 text,
year_2003 text,
year_2004 text,
year_2005 text,
year_2006 text,
year_2007 text,
year_2008 text,
year_2009 text,
year_2010 text,
year_2011 text);

//编辑

感谢欧文,它现在可以工作了,但我尝试在没有内置功能的情况下做到这一点,但没有成功。有人可以对此提出建议吗?我的代码只用了两年:

SELECT DISTINCT o.client_id,
       CASE WHEN (extract(year from o.date)=2001)
            THEN sum(o.amount) ELSE 0 END,
       CASE WHEN (extract(year from o.date)=2002)
            THEN sum(o.amount) ELSE 0 END
FROM orders AS o
GROUP BY 1, extract(year from o.date)
ORDER BY 1;

最佳答案

您需要ORDER BY相应地第一个查询。我用simplified syntax ORDER BY <ordinal number>在这里。

SELECT *
FROM   crosstab(
        'SELECT client_id
               ,extract(year from date)
               ,sum(amount)
         FROM   orders
         GROUP  BY 1,2
         ORDER  BY 1,2',

        'SELECT extract(year from date)
         FROM   orders
         GROUP  BY 1
         ORDER  BY 1')
AS orders(
    row_name integer,
    year_2001 text,
    year_2002 text,
    year_2003 text,
    year_2004 text,
    year_2005 text,
    year_2006 text,
    year_2007 text,
    year_2008 text,
    year_2009 text,
    year_2010 text,
    year_2011 text);

crosstab()函数不包含在标准 PostgreSQL 中,但附带 additional module tablefunc .

编辑其他请求

没有 crosstab() 的版本功能: 仅按 client_id 分组或者你最终会得到每个 client_id 的多行.

SELECT client_id
      ,sum(CASE WHEN extract(year from date) = 2001 THEN amount ELSE 0 END) AS year_2001
      ,sum(CASE WHEN extract(year from date) = 2002 THEN amount ELSE 0 END) AS year_2002
       -- ...
FROM   orders o
GROUP  BY 1
ORDER  BY 1;

关于sql - 使用交叉表函数的 PostgreSQL 和数据透视表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8027293/

相关文章:

sql - 修剪 sql 变体

SQL Left Join 对每个表进行验证

Windows 上的 PostgreSQL 12.0 Git Bash 与 createDB 发生冲突

sql - 如何对 postgres 中两列的乘积求和并按两列分组?

mysql - 与 INNER JOIN 作斗争

SQL: JOIN 与 'near' 匹配

php - SQL 查询中的 While 循环

sql - 使用 EAV 表连接/旋转项目

r - 使用一个指示更新日期的变量将时间相关变量转换为长格式

sql-server - SQL Server 数据透视查询不采用空计数