Postgres SQL查询 - 每月平均值

时间:2017-07-17 03:57:42

标签: sql postgresql

我想要实现两个查询。

我有一张这样的桌子......

Date        | Period | Location | Price
2017-01-01      1         A         10
2017-01-01      2         A         15
2017-01-01      1         B         15
2017-01-01      2         B         16

每个日期有48个读数(每半小时一个)。

查询1:我希望以下列格式获取日期范围内任何给定地点的平均价格:

e.g。在2017-01-01和2017-06-30之间,地点的平均价格为A'

  Period 1  | Period 2|  Period 3 ...
       10           11          15

查询2:我希望任何给定位置的平均价格可以追溯x个月:(期间无关紧要)

Month   |  Average price
january        10
february       12
march          16

非常感谢任何帮助:)

2 个答案:

答案 0 :(得分:0)

您列出的第二个查询是一个非常简单的group by操作。唯一有点棘手的是你需要从列出的日期中提取月份。

select
    date_part('month', t.Date) as month
    avg(t.Price) as average_price
from
    mytable t
group by
    date_part('month', t.Date)

然而,第一个查询要复杂得多。它涉及crosstab(),如果您还没有,则必须在数据库中启用该select * from crosstab( ' select t.Period , avg(t.Price) as avg_price from mytable t group by t.Period order by 1 , 2 ' ) as ct( "Period" text , "1" int , "2" int , "3" int , "4" int , "5" int , "6" int , "7" int , "8" int , "9" int , "10" int , "11" int , "12" int ) 。一般的想法是计算每个时期的平均值,然后像在excel中那样转动数据。

crosstab()

answer有关于Postgre的/path/workspace/.metadata/

的大量信息

答案 1 :(得分:0)

第一个问题:

您需要一个枢轴。如果您不想以静态方式执行此操作(在查询中手动命名所有期间列),则可以使用JSON以更动态的方式实现:

SQL Fiddle Query

结果:

\\\"

您将获得一个JSON字符串,该字符串可用于进一步的计算,例如

{"Period 1": 15.0000000000000000, "Period 2": 22.5000000000000000, "Period 3": 100.0000000000000000, "Period 4": 150.0000000000000000}

请参阅此处:SQL Fiddle: Further calculation

使用JSON函数,您可以获得动态的伪数据透视结果。

查询:

SELECT json_pivot -> 'Period 2' FROM (/* subquery */)

A:按地点和期间分组,将期间编号重命名为“期间[number]”

B:SELECT jsonb_object_agg(period, avg) as pivot_json -- B FROM ( SELECT 'Period ' || period as period, AVG(price) -- A FROM period_prices pp WHERE location = 'A' AND date BETWEEN '2017-01-01' AND '2017-06-30' GROUP BY location, period )s 将两列汇总到显示的结果。

https://www.postgresql.org/docs/current/static/functions-json.html

https://www.postgresql.org/docs/current/static/functions-aggregate.html


第二个问题是一个简单的jsonb_object_aggSQL Fiddle

GROUP BY

您可以按SELECT to_char(pp.date, 'month') as month, avg(pp.price) as avg_price FROM period_prices pp GROUP BY to_char(pp.date, 'month') 分组。但是,尽管date_part为您提供了月份数(这是进行进一步计算的首选解决方案),但您希望最后获得月份的名称。为此,您可以使用date_part('month', ...)函数。

https://www.postgresql.org/docs/current/static/functions-formatting.html