带有CASE和聚合的PostgreSQL crosstab()替代

编程入门 行业动态 更新时间:2024-10-17 11:28:40
本文介绍了带有CASE和聚合的PostgreSQL crosstab()替代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我想创建一个数据透视表视图,以显示每个travel_mode的每月预订总金额.

I want to create a pivot table view showing month on month sum of bookings for every travel_mode.

表bookings:

timestamp , bookings , provider_id

表providers:

provider_id , travel_mode

不要使用数据透视表功能和交叉表功能.所以我正在尝试使用JOIN和CASE.以下是查询:

Pivot table function and crosstab functions are not to be used to do this. So I am trying to use JOIN and CASE. Following is the query:

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;

但是我收到一条错误消息:

However I am getting an error which says:

subquery in FROM must have an alias LINE 6:

当我添加一个别名时,它会抛出一个错误:

And when I add an alias it throws an error saying:

column p.travel_mode must appear in the GROUP BY clause or be used in an aggregate function LINE 2:

最终结果应该是这样

Month Air Bus Train 01 Amount(air) Amount(Bus) Amount(train)

我觉得在某个地方这是一个小错误,但我根本无法弄清楚.

I have a feeling it is a minor error somewhere but I am unable to figure it out at all.

P.S.我不得不删除问题中的所有引号,因为它不允许我发布此内容.但是在实际查询中会解决这些问题.

P.S. I had to remove all quotations in the question as it was not allowing me to post this. But those are being taken care of in the actual query.

推荐答案

多个问题.缺少的表别名只是其中之一.此查询应该可以工作:

Multiple problems. The missing table alias is just one of them. This query should work:

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;

  • 缺少字符串文字的单引号. (您似乎已删除了那些无法发布报价的错误印象.)

    • Missing single quotes for string literals. (You seem to have removed those being under the wrong impression you couldn't post quotations.)

      缺少子查询的表别名-就像第一条错误消息所说的一样.

      Missing table alias for the subquery - just like the 1st error message says.

      在外部查询中,子查询中基础表的表名(或别名)不可见.只有子查询的表别名是.由于只有一个 子查询,因此您根本不需要表限定.

      In the outer query, table names (or aliases) of underlying tables in the subquery are not visible. Only the table alias of the subquery is. Since there is only one subquery, you don't need table-qualification at all there.

      month是输出列名称(不在基础表中),因此表限定符b.month也是错误的.

      month is an output column name (not in the underlying table), so the table qualification b.month was wrong, too.

      您似乎想要几个月的2位数字.使用模板模式'MM'而不是to_char()的月".

      You seem to want 2-digit numbers for months. Use the template pattern 'MM' instead of 'month' with to_char().

      外部查询中的聚合不能像您遇到的那样工作-就像您的第二条错误消息所说的那样.您必须将外部CASE表达式包装在聚合函数中.在这种情况下,您也可以使用min()或max(),因为子查询之后的行永远不会超过一排.

      The aggregation in the outer query does not work like you had it - just like your 2nd error message says. You have to wrap the outer CASE expression in a aggregate function. You might as well use min() or max() in this case, because there are never more than one rows after the subquery.

      仍不清楚date_来自何处?您是说timestamp? (这不是一个很好的标识符).

      Still unclear where date_ is coming from? You mean timestamp? (which is not a good identifier).

      但是您不需要子查询开头,并且可以简化为:

      But you don't need the subquery to begin with and can simplify to:

      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;

      为获得最佳性能,您仍应使用crosstab(),

      For best performance you should still use crosstab(), though:

      • PostgreSQL交叉表查询

更多推荐

带有CASE和聚合的PostgreSQL crosstab()替代

本文发布于:2023-11-22 06:02:55,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1616241.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:CASE   PostgreSQL   crosstab

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!