Answers:
select to_char(date,'Mon') as mon,
extract(year from date) as yyyy,
sum("Sales") as "Sales"
from yourtable
group by 1,2
应Radu的要求,我将解释该查询:
to_char(date,'Mon') as mon,
:将“日期”属性转换为月的简短形式的定义格式。
extract(year from date) as yyyy
:Postgresql的“提取”功能用于从“日期”属性中提取YYYY年。
sum("Sales") as "Sales"
:SUM()函数将所有“ Sales”值相加,并提供区分大小写的别名,并使用双引号保持区分大小写。
group by 1,2
:GROUP BY函数必须包含SELECT列表中不属于聚合的所有列(aka,所有列均不在SUM / AVG / MIN / MAX等函数之内)。这告诉查询应该将SUM()应用于每个唯一的列组合,在这种情况下为月和年列。尽管可以最好使用完整的“ to_char(...)”和“ extract(...)”表达式,但“ 1,2”部分是简化的方式,而不是使用列别名。
date_trunc
内容与select date_trunc('month', timestamp '2001-02-16 20:38:40')::date
2001-02-01
date_trunc
在group by
子句中使用的想法。
我不敢相信已接受的答案会有这么多否定-这是一种可怕的方法。
这是使用date_trunc的正确方法:
SELECT date_trunc('month', txn_date) AS txn_month, sum(amount) as monthly_sum
FROM yourtable
GROUP BY txn_month
这是不好的做法,但是如果您使用
GROUP BY 1
在一个非常简单的查询中。
您也可以使用
GROUP BY date_trunc('month', txn_date)
如果您不想选择日期。
date_trunc
不是asker期望的: select date_trunc('month', timestamp '2001-02-16 20:38:40')
=> 2001-02-01 00:00:00
。
to_char(date_trunc('month', txn_date), 'YY-Mon')
date_trunc
就是为此目的而创建的。没有理由创建两列
to_char
实际上让您一举掏出年月!
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'
或在上述用户示例的情况下:
select to_char(date,'YY-Mon') as year_month
sum("Sales") as "Sales"
from some_table
group by 1;
date_trunc
通过执行组时方法。我在数据库上进行实验非常方便,在具有270k行的表上,date_trunc方法的速度是TO_CHAR速度的两倍
bma的答案很棒!我已经将它与ActiveRecords一起使用,这是在Rails中是否有人需要它的地方:
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"
)
yourscopeorclass.group("extract(year from tablename.colname)")
,也可以将其链接在一起3次以获取年,月,日
看一下本教程的示例E-> https://www.postgresqltutorial.com/postgresql-group-by/
您需要在GROUP BY上调用该函数,而不是调用在select上创建的虚拟属性的名称。我正在按照上面建议的所有答案进行操作,但出现column 'year_month' does not exist
错误。
对我有用的是:
SELECT
date_trunc('month', created_at), 'MM/YYYY' AS month
FROM
"orders"
GROUP BY
date_trunc('month', created_at)
Postgres有几种类型的时间戳:
没有时区的时间戳 -(最好存储UTC时间戳)您可以在跨国数据库存储中找到它。在这种情况下,客户将照顾每个国家/地区的时区偏移量。
带时区的时间戳 -时区偏移已包含在时间戳中。
在某些情况下,您的数据库不使用时区,但是您仍然需要根据本地时区和夏时制对记录进行分组(例如https://www.timeanddate.com/time/zone/romania/bucharest)
要添加时区,您可以使用此示例,并将时区偏移量替换为您的时区偏移量。
"your_date_column" at time zone '+03'
要添加特定于DST的+1夏令时偏移,您需要检查时间戳是否属于夏令时。由于这些间隔每隔1天或2天变化一次,因此我将使用不影响月末记录的近似值,因此在这种情况下,我可以忽略每年的确切间隔。
如果必须构建更精确的查询,则必须添加条件才能创建更多案例。但是粗略地讲,当您在数据库中找到没有时区的时间戳时,这对于按时区和SummerTime每月拆分数据会很好:
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)