Group query results by month and year in postgresql
我在Postgres服务器上有以下数据库表:
1 2 3 4 5 | id DATE Product Sales 1245 01/04/2013 Toys 1000 1245 01/04/2013 Toys 2000 1231 01/02/2013 Bicycle 50000 456461 01/01/2014 Bananas 4546 |
我想创建一个查询,给出
1 2 3 | Apr 2013 3000 Toys Feb 2013 50000 Bicycle Jan 2014 4546 Bananas |
有简单的方法吗?
我不能相信有这么多的答案upvotes接受——这是一个挺吓人的方法。
这是做它的方式correct,与_ trunc日期:
1 2 3 | SELECT date_trunc('month', txn_date) AS txn_month, SUM(amount) AS monthly_sum FROM yourtable GROUP BY txn_month |
这是不好的做法,但你可能forgiven如果你使用
1 | GROUP BY 1 |
在一个非常简单的查询。
你可以同时使用
1 | GROUP BY date_trunc('month', txn_date) |
如果你不想选择的日期。
1 2 3 4 5 | SELECT to_char(DATE,'Mon') AS mon, EXTRACT(YEAR FROM DATE) AS yyyy, SUM("Sales") AS"Sales" FROM yourtable GROUP BY 1,2 |
在请求的Radu,我不能解释,将查询:
1 2 | SELECT to_char(DATE('2014-05-10'),'Mon-YY') AS year_month; --'May-14' SELECT to_char(DATE('2014-05-10'),'YYYY-MM') AS year_month; --'2014-05' |
在的情况下的用户,或以上的例子:
1 2 3 4 | SELECT to_char(DATE,'YY-Mon') AS year_month SUM("Sales") AS"Sales" FROM some_table GROUP BY 1; |
有另一种方式以实现的结果使用日期_部分在postgres()函数。
1 2 3 | SELECT date_part('month', txn_date) AS txn_month, date_part('year', txn_date) AS txn_year, SUM(amount) AS monthly_sum FROM yourtable GROUP BY date_part('month', txn_date) |
谢谢你
bma回答是伟大的!我已经用它与activerecords,在这里它是:如果有人需要它在rails
1 2 3 4 5 6 7 8 | Model.find_by_sql( "SELECT TO_CHAR(created_at, 'Mon') AS month, EXTRACT(year from created_at) as year, SUM(desired_value) as desired_value FROM desired_table GROUP BY 1,2 ORDER BY 1,2" ) |
有一些类型的timestamps:postgres
timestamp无timezone -(preferable大商店timestamps GMT)你找到它在multinational数据库存储。在这种情况下的client会照顾的timezone粒状为每个国家。
timestamp与timezone - timezone粒状是已经包括在timestamp。
在一些情况下,你的数据库使用的timezone不做,但你仍然需要记录在本地组的老学校的武器与saving timezone和日光时间(例如HTTPS www.timeanddate.com /:/ / / / /罗马尼亚布加勒斯特Time Zone)
你可以添加大timezone使用这个例子和取代的timezone粒状与你。
1 | "your_date_column" at TIME zone '+03' |
添加一个夏天的时间大大+粒状dst具体你需要检查如果你的timestamp dst落在一个夏天。作为这些变化的intervals与一或两天,我会使用不安全的aproximation,并不影响最后的月记录,所以在这种情况下,我可以忽略每年interval准确。
如果更多的precise查询已成为建立,然后你必须添加更大的情况下,创造了条件。但大约在splitting罚款,这将工作数据,每月在老学校的武器与timezone和夏季,当你发现在你的timestamp无timezone数据库:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | SELECT "id","Product","Sale", date_trunc('month', CASE WHEN EXTRACT(MONTH FROM t."date") > 03 AND EXTRACT(DAY FROM t."date") > 26 AND EXTRACT(HOUR FROM t."date") > 3 AND EXTRACT(MONTH FROM t."date") < 10 AND EXTRACT(DAY FROM t."date") < 29 AND EXTRACT(HOUR FROM t."date") < 4 THEN t."date" at TIME zone '+03' -- Romania TimeZone offset + DST ELSE t."date" at TIME zone '+02' -- Romania TimeZone offset END) AS"date" FROM public."Table" AS t WHERE 1=1 AND t."date">= '01/07/2015 00:00:00'::TIMESTAMP WITHOUT TIME ZONE AND t."date" < '01/07/2017 00:00:00'::TIMESTAMP WITHOUT TIME ZONE GROUP BY date_trunc('month', CASE WHEN EXTRACT(MONTH FROM t."date") > 03 AND EXTRACT(DAY FROM t."date") > 26 AND EXTRACT(HOUR FROM t."date") > 3 AND EXTRACT(MONTH FROM t."date") < 10 AND EXTRACT(DAY FROM t."date") < 29 AND EXTRACT(HOUR FROM t."date") < 4 THEN t."date" at TIME zone '+03' -- Romania TimeZone offset + DST ELSE t."date" at TIME zone '+02' -- Romania TimeZone offset END) |