我使用的是 PostgreSQL 9.3 版本的数据库。
我有一种情况,我想计算产品销售数量并对产品数量求和,还想在产品销售的列中显示城市。
例子
设置
create table products (
name varchar(20),
price integer,
city varchar(20)
);
insert into products values
('P1',1200,'London'),
('P1',100,'Melborun'),
('P1',1400,'Moscow'),
('P2',1560,'Munich'),
('P2',2300,'Shunghai'),
('P2',3000,'Dubai');
交叉表查询:
select * from crosstab (
'select name,count(*),sum(price),city,count(city)
from products
group by name,city
order by name,city
'
,
'select distinct city from products order by 1'
)
as tb (
name varchar(20),TotalSales bigint,TotalAmount bigint,London bigint,Melborun bigint,Moscow bigint,Munich bigint,Shunghai bigint,Dubai bigint
);
输出
name totalsales totalamount london melborun moscow munich shunghai dubai
---------------------------------------------------------------------------------------------------------
P1 1 1200 1 1 1
P2 1 3000 1 1 1
预期输出:
name totalsales totalamount london melborun moscow munich shunghai dubai
---------------------------------------------------------------------------------------------------------
P1 3 2700 1 1 1
P2 3 6860 1 1 1
最佳答案
您的第一个错误似乎很简单。根据 crosstab()
函数的第二个参数,'Dubai'
必须作为第一个城市(按城市排序)。详情:
totalsales
和 totalamount
的意外值表示每个 name
组第一行的值。 “额外”列被这样对待。详情:
要获取每个 name
的总和,请在聚合函数上运行窗口函数。详情:
select * from crosstab (
'select name
,sum(count(*)) OVER (PARTITION BY name)
,sum(sum(price)) OVER (PARTITION BY name)
,city
,count(city)
from products
group by name,city
order by name,city
'
-- ,'select distinct city from products order by 1' -- replaced
,$$SELECT unnest('{Dubai,London,Melborun
,Moscow,Munich,Shunghai}'::varchar[])$$
) AS tb (
name varchar(20), TotalSales bigint, TotalAmount bigint
,Dubai bigint
,London bigint
,Melborun bigint
,Moscow bigint
,Munich bigint
,Shunghai bigint
);
更好的是,提供一个静态集作为第二个参数。输出列是硬编码的,动态生成数据列可能不可靠。如果你在新城市的另一行,这将中断。
通过这种方式,您还可以根据需要对列进行排序。只需保持输出列和第二个参数同步。
关于sql - 使用 PostgreSQL 的交叉表查询中的计数和总和无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28562244/