如何在 Postgres 中使用时间戳字段对日期进行分组?
Posted
技术标签:
【中文标题】如何在 Postgres 中使用时间戳字段对日期进行分组?【英文标题】:How to GROUP BY date with a timestamp field in Postgres? 【发布时间】:2018-07-28 05:42:02 【问题描述】:假设我有 3 行数据:
id product_uuid version_uuid created_at
22 586d8e21b9529d14801b91bd 5a711a0094df04e23833d8ef 2018-02-10 19:51:15.075-05
23 586d8e21b9529d14801b91bd 5a711a0094df04e23833d8ef 2018-02-10 19:51:16.077-07
24 586d8e21b9529d14801b91bd 5a711a0094df04e23833d8ef 2018-02-11 19:51:15.077-05
我想通过created_at
列按天对它们进行分组。
SELECT created_at::date, COUNT(*)
FROM table_name
WHERE product_uuid = '586d8e21b9529d14801b91bd'
AND created_at > now() - interval '30 days'
GROUP BY created_at
ORDER BY created_at ASC
我希望这会产生 2 行:
created_at count
2018-02-10 2
2018-02-11 1
但我实际上得到了 3 行:
created_at count
2018-02-10 1
2018-02-10 1
2018-02-11 1
我意识到GROUP BY
仍在按细粒度时间戳分组,但我不确定如何让 Postgres 使用截断的日期。
【问题讨论】:
【参考方案1】:您需要format 将日期作为字符串。所以改为这样做:
SELECT to_char(created_at,'YYYY-MM-DD'), COUNT(*) AS `Count`
FROM table_name
WHERE product_uuid = '586d8e21b9529d14801b91bd'
AND created_at > now() - interval '30 days'
GROUP BY to_char(created_at,'YYYY-MM-DD')
ORDER BY to_char(created_at,'YYYY-MM-DD') ASC;
【讨论】:
【参考方案2】:您可以按单个时间戳(包括一天中的时间)查询组,然后在分组后将它们转换为日期。如果你想要每个日期的 rwo,你也应该在 group by
子句中添加到 date
的转换:
SELECT created_at::date, COUNT(*)
FROM table_name
WHERE product_uuid = '586d8e21b9529d14801b91bd'
AND created_at > now() - interval '30 days'
GROUP BY created_at::date -- Here!
ORDER BY created_at 1 ASC
【讨论】:
【参考方案3】:您还需要在GROUP BY
中截断:
SELECT created_at::date, COUNT(*)
FROM table_name
WHERE product_uuid = '586d8e21b9529d14801b91bd' AND
created_at > now() - interval '30 days'
GROUP BY created_at::date
ORDER BY created_at::date ASC;
您的版本按每个日期/时间值汇总,但仅显示日期部分。
另外,我建议您使用current_date
而不是now()
,这样第一个日期就不会被截断。
【讨论】:
以上是关于如何在 Postgres 中使用时间戳字段对日期进行分组?的主要内容,如果未能解决你的问题,请参考以下文章
在 postgres 中,如何从事件日志类型表(具有时间戳)中获取特定时间范围内字段的总和(或汇总)