在postgresql中排列选择查询?

在postgresql中排列选择查询?,sql,postgresql,pivot,crosstab,Sql,Postgresql,Pivot,Crosstab,我有一个问题: select channel, status, sum(quantity::integer) from sale group by channel,status; 这将提供以下输出: channel status quantity Arham Return 1801 Arham DISPATCHED 49934 Arham CANCELLED 1791 Arham DELIVERED 22 但是我想要这样的输

我有一个问题:

select channel, status, sum(quantity::integer) 
from sale group by channel,status;
这将提供以下输出:

channel  status       quantity
Arham    Return       1801
Arham    DISPATCHED   49934
Arham    CANCELLED    1791
Arham    DELIVERED    22
但是我想要这样的输出:

channel   return   DISPATCHED   CANCELLED  DELIVERED  
Arham     1801     49934        1791       22
在postgresql中可能吗? 如果是,那么如何使用

首先,您需要创建扩展

create extension if not exists tablefunc;
问题是

SELECT *
FROM   crosstab(
      'select channel::text
             ,status
             ,sum(quantity::integer) 
       from sale group by channel,status')  
AS ct ("channel" text, "Return" int, "DISPATCHED" int, "CANCELLED" int, "DELIVERED" int);
使用

首先,您需要创建扩展

create extension if not exists tablefunc;
问题是

SELECT *
FROM   crosstab(
      'select channel::text
             ,status
             ,sum(quantity::integer) 
       from sale group by channel,status')  
AS ct ("channel" text, "Return" int, "DISPATCHED" int, "CANCELLED" int, "DELIVERED" int);

利用布尔到整数的转换,给出0或1,然后乘以:

select channel
     , sum((status = 'Return') :: int * quantity :: int) as return
     , sum((status = 'DISPATCHED') :: int * quantity :: int) as DISPATCHED
     , sum((status = 'CANCELLED') :: int * quantity :: int) as CANCELLED
     , sum((status = 'DELIVERED') :: int * quantity :: int) as DELIVERED
from sale
group by channel
等效的解决方案是在/
然后
时使用案例/
,例如:

sum(case when status = 'Return' then quantity :: int else 0 end)

利用布尔到整数的转换,给出0或1,然后乘以:

select channel
     , sum((status = 'Return') :: int * quantity :: int) as return
     , sum((status = 'DISPATCHED') :: int * quantity :: int) as DISPATCHED
     , sum((status = 'CANCELLED') :: int * quantity :: int) as CANCELLED
     , sum((status = 'DELIVERED') :: int * quantity :: int) as DELIVERED
from sale
group by channel
等效的解决方案是在
/
然后
时使用案例/
,例如:

sum(case when status = 'Return' then quantity :: int else 0 end)

如果您不想使用
交叉表
功能,可以使用过滤的聚合:

select channel,
       sum(quantity) filter (where status = 'Return') as return_amount,
       sum(quantity) filter (where status = 'DISPATCHED') as dispatched,
       sum(quantity) filter (where status = 'CANCELLED') as cancelled,
       sum(quantity) filter (where status = 'DELIVERED') as delivered
from sale
group by channel;

如果您不想使用
交叉表
功能,可以使用过滤的聚合:

select channel,
       sum(quantity) filter (where status = 'Return') as return_amount,
       sum(quantity) filter (where status = 'DISPATCHED') as dispatched,
       sum(quantity) filter (where status = 'CANCELLED') as cancelled,
       sum(quantity) filter (where status = 'DELIVERED') as delivered
from sale
group by channel;

它给出错误:
错误:返回类型详细信息无效:SQL rowid数据类型与返回rowid数据类型不匹配。
每列的数据类型是什么?每列最初都有varchar数据类型。@yam:为什么要将
数量
存储为
varchar
?永远不要在
varchar
列中存储数字。不要那样做。@一匹没有名字的马你是对的。当处理部分完成时,我将更新我的所有数据库。之后,我将以标准形式改进我的数据库。thanksit给出错误:
错误:返回类型详细信息无效:SQL rowid数据类型与返回rowid数据类型不匹配。
每列的数据类型是什么?每列最初都有varchar数据类型。@yam:为什么要将
数量
存储为
varchar
?永远不要在
varchar
列中存储数字。不要那样做。@一匹没有名字的马你是对的。当处理部分完成时,我将更新我的所有数据库。之后,我将以标准形式改进我的数据库。thanks@YAM类似于
status='Return'
的比较结果为true或false。将true转换为整数时,得到一个。将false转换为整数时,得到零。将任何值乘以0即为0,将任何值乘以1即为原始值<代码>求和
实际上忽略了零。有一件事我忘了。当你应该问一个新问题时,状态可能是动态的。请参阅。@YAM比较,如
status='Return'
结果为true或false。将true转换为整数时,得到一个。将false转换为整数时,得到零。将任何值乘以0即为0,将任何值乘以1即为原始值<代码>求和实际上忽略了零。有一件事我忘了。当你应该问一个新问题时,状态可能是动态的。看见