我在Postgres服务器上有以下数据库表:
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
我想创建一个查询,它给出Sales
列的SUM
,并按月和年对结果进行分组,如下所示:
Apr 2013 3000 Toys
Feb 2013 50000 Bicycle
Jan 2014 4546 Bananas
有没有简单的方法可以做到这一点?
8条答案
按热度按时间goqiplq21#
我不敢相信被接受的答案有这么多的赞成票--这是一个可怕的方法。
下面是使用date_trunc执行此操作的正确方法:
这是不好的做法,但你可能会被原谅,如果你使用
一个非常简单的查询。
您也可以使用
如果你不想选择日期。
j5fpnvbx2#
应拉杜的要求,我将解释这个问题:
to_char(date,'Mon') as mon,
:将"date"属性转换为month缩写形式的定义格式。extract(year from date) as yyyy
:Postgresql的"extract"函数用于从"date"属性中提取YYYY年。sum("Sales") as "Sales"
:SUM()函数将所有"Sales"值相加,并提供一个区分大小写的别名,通过使用双引号保持区分大小写。group by 1,2
:GROUP BY函数必须包含SELECT列表中不属于聚合的所有列(也就是不在SUM/AVG/MIN/MAX等函数中的所有列)。这告诉查询SUM()应用于每个唯一的列组合,在本例中是月列和年列。"1,2"部分是一个缩写,而不是使用列别名,尽管为了可读性,最好使用完整的"to_char(...)"和"extract(...)"表达式。xxls0lw83#
to_char
实际上可以让你一举拉出年和月!或者在上述用户示例的情况下:
hujrc8aj4#
还有另一种方法可以使用postgres中的date_part()函数来获得结果。
谢谢
hfyxw5xn5#
为什么不直接使用
date_part
函数。https://www.postgresql.org/docs/8.0/functions-datetime.htmlzed5wv106#
查看本教程的示例6)-〉https://www.postgresqltutorial.com/postgresql-group-by/
你需要调用GROUP BY上的函数,而不是调用你在select上创建的虚拟属性的名称。我正在做上面所有答案推荐的事情,我得到了一个
column 'year_month' does not exist
错误。对我有效的是:
deyfvvtc7#
Postgres有几种类型的时间戳:
不带时区的时间戳-(最好存储UTC时间戳)您可以在多国数据库存储中找到它。在这种情况下,客户端将负责每个国家的时区偏移。
带时区的时间戳-时间戳中已包含时区偏移量。
在某些情况下,您的数据库不使用时区,但您仍然需要根据本地时区和夏令时对记录进行分组(例如https://www.timeanddate.com/time/zone/romania/bucharest)
要添加时区,您可以使用此示例并将时区偏移替换为您的时区偏移。
要添加特定于DST的+1夏令时偏移量,您需要检查您的时间戳是否福尔斯夏令时。由于这些间隔在1或2天内变化,我将使用不影响月末记录的近似值,因此在本例中,我可以忽略每年的确切间隔。
如果必须构建更精确的查询,那么您必须添加条件来创建更多的案例。但粗略地说,当您在数据库中找到不带时区的时间戳时,根据时区和SummerTime每月拆分数据时,这将工作得很好:
ftf50wuq8#
我还需要查找按年和月分组的结果。当我按时间戳分组时,求和函数按日期和分钟分组,但这不是我想要的。使用此查询可能对您有帮助。
transactions tablequery result如图所示,在“2022-07-01”中,我在表中有两列,在查询结果中它们被分组在一起。