PostgreSQL crosstab()选项,带大小写和聚合
我想创建一个透视表视图,显示每个PostgreSQL crosstab()选项,带大小写和聚合,postgresql,join,case,aggregate,crosstab,Postgresql,Join,Case,Aggregate,Crosstab,我想创建一个透视表视图,显示每个旅行模式下的每月预订总数 表预订量: timestamp , bookings , provider_id 表提供者: provider_id , travel_mode 透视表函数和交叉表函数不用于执行此操作。所以我尝试使用JOIN和CASE。以下是查询: SELECT b.month, (CASE WHEN p.travel_mode=train then b.amount end)train, (CASE WHEN p.travel
旅行模式下的每月预订总数
表预订量:
timestamp
, bookings
, provider_id
表提供者
:
provider_id
, travel_mode
透视表函数和交叉表函数不用于执行此操作。所以我尝试使用JOIN和CASE。以下是查询:
SELECT b.month,
(CASE WHEN p.travel_mode=train then b.amount end)train,
(CASE WHEN p.travel_mode=bus then b.amount end)bus,
(CASE WHEN p.travel_mode=air then b.amount end)air
FROM
(SELECT to_char(date_,month) as month, travel_mode, sum(bookings) as amount
from bookings as b
join providers as p
on b.provider_id=p.provider_id
group by b.month, p.travel_mode)
group by b.month;
然而,我得到一个错误,它说:
当我添加别名时,它会抛出一个错误,说:
最终结果应该是这样的
Month Air Bus Train
01 Amount(air) Amount(Bus) Amount(train)
我有一种感觉,这是一个小错误的地方,但我无法找出它在所有
另外,我不得不删除问题中的所有引文,因为它不允许我发布这篇文章。但是这些都在实际查询中处理。您必须将子查询命名为错误消息所示的名称:
SELECT b.month,
(CASE WHEN p.travel_mode=train then b.amount end)train,
(CASE WHEN p.travel_mode=bus then b.amount end)bus,
(CASE WHEN p.travel_mode=air then b.amount end)air
FROM
(SELECT to_char(date_,month) as month, travel_mode, sum(bookings) as amount
from bookings as b
join providers as p
on b.provider_id=p.provider_id
group by b.month, p.travel_mode)
**as foo** group by b.month;
删除星号以使其工作。多个问题。缺少的表别名只是其中之一。此查询应适用于以下情况:
SELECT month
, sum(CASE WHEN travel_mode = 'train' THEN amount END) AS train
, sum(CASE WHEN travel_mode = 'bus' THEN amount END) AS bus
, sum(CASE WHEN travel_mode = 'air' THEN amount END) AS air
FROM (
SELECT to_char(timestamp, 'MM') AS month, travel_mode, sum(bookings) AS amount
FROM bookings b
JOIN providers p USING (provider_id)
GROUP BY month, p.travel_mode
) sub
GROUP BY month;
- 字符串文字缺少单引号。(你似乎已经删除了那些你无法发布报价的错误印象。)
- 子查询缺少表别名-如第一条错误消息所示
- 在外部查询中,子查询中基础表的表名(或别名)不可见。只有子查询的表别名是。因为只有一个子查询,所以根本不需要表限定
month
是一个输出列名(不在基础表中),因此表限定b.month
也是错误的
- 你似乎想要几个月的两位数数字。使用“
to_char()”
代替“month”
- 外部查询中的聚合不像您之前那样工作-就像您的第二条错误消息所说的那样。必须将外部
大小写
表达式包装在聚合函数中。在这种情况下,您最好使用min()
或max()
,因为子查询后面的行永远不会超过一行
- 还不清楚日期从哪里来?你是说时间戳?(这不是一个好的标识符)
但您不需要从子查询开始,可以简化为:
SELECT to_char(timestamp, 'MM') AS month
, sum(CASE WHEN p.travel_mode = 'train' THEN b.bookings END) AS train
, sum(CASE WHEN p.travel_mode = 'bus' THEN b.bookings END) AS bus
, sum(CASE WHEN p.travel_mode = 'air' THEN b.bookings END) AS air
FROM bookings b
JOIN providers p USING (provider_id)
GROUP BY 1;
为获得最佳性能,您仍应使用交叉表()
,不过:
您可以(也应该)发布所有报价。因此,这当然是允许的。您应该始终添加实际的表定义(CREATE table
语句),显示数据类型和约束以及您的Postgres版本。第一次查询不起作用。这是它抛出的错误错误:列b.month不存在第9行:按b.month分组,p.travel\u mode^@justanothernewbie:现在已修复。请尝试最新版本。(month
是一个输出列名,因此表限定错误。)
SELECT month
, sum(CASE WHEN travel_mode = 'train' THEN amount END) AS train
, sum(CASE WHEN travel_mode = 'bus' THEN amount END) AS bus
, sum(CASE WHEN travel_mode = 'air' THEN amount END) AS air
FROM (
SELECT to_char(timestamp, 'MM') AS month, travel_mode, sum(bookings) AS amount
FROM bookings b
JOIN providers p USING (provider_id)
GROUP BY month, p.travel_mode
) sub
GROUP BY month;
SELECT to_char(timestamp, 'MM') AS month
, sum(CASE WHEN p.travel_mode = 'train' THEN b.bookings END) AS train
, sum(CASE WHEN p.travel_mode = 'bus' THEN b.bookings END) AS bus
, sum(CASE WHEN p.travel_mode = 'air' THEN b.bookings END) AS air
FROM bookings b
JOIN providers p USING (provider_id)
GROUP BY 1;