Postgres count number or rows and group them by timestamp
假设我在postgres中有一个只有2列的表:
-
ID 表格的PK(bigint ) -
time 是timestamp 的类型
是否有任何方法可以获得按时间分组的ID BYYEAR-当时间是2005年2月18日它将适合2005年组(因此结果将是)
1 2 3 | YEAR NUMBER OF ROWS 1998 2 2005 5 |
如果结果行的数量小于某个数字(例如3),则SQL将按月返回结果
就像是
1 2 3 | MONTH NUMBER OF ROWS (February 2018) 5 (March 2018) 2 |
这可能是postgres SQL的一些好方法吗?
您可以使用窗口函数(一如既往)来完成。
我用这个表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | TABLE times; id | t ----+------------------------------- 1 | 2018-03-14 20:04:39.81298+01 2 | 2018-03-14 20:04:42.92462+01 3 | 2018-03-14 20:04:45.774615+01 4 | 2018-03-14 20:04:48.877038+01 5 | 2017-03-14 20:05:08.94096+01 6 | 2017-03-14 20:05:16.123736+01 7 | 2017-03-14 20:05:19.91982+01 8 | 2017-01-14 20:05:32.249175+01 9 | 2017-01-14 20:05:35.793645+01 10 | 2017-01-14 20:05:39.991486+01 11 | 2016-11-14 20:05:47.951472+01 12 | 2016-11-14 20:05:52.941504+01 13 | 2016-10-14 21:05:52.941504+02 (13 ROWS) |
首先,逐月分组(子查询
然后使用窗口函数(子查询
最后,使用
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 | SELECT DISTINCT CASE WHEN yc > 5 THEN mc ELSE yc END AS COUNT, CASE WHEN yc > 5 THEN to_char(t, 'YYYY-MM') ELSE to_char(t, 'YYYY') END AS period FROM (SELECT mc, SUM(mc) OVER (PARTITION BY date_trunc('year', t)) AS yc, t FROM (SELECT COUNT(*) AS mc, date_trunc('month', t) AS t FROM times GROUP BY date_trunc('month', t) ) per_month ) with_year ORDER BY 2; COUNT | period -------+--------- 3 | 2016 3 | 2017-01 3 | 2017-03 4 | 2018 (4 ROWS) |
算几年吧。 如果它至少为3,则按年分组,否则按月分组:
1 2 3 4 5 6 7 8 9 10 | SELECT CASE (SELECT COUNT(DISTINCT EXTRACT(YEAR FROM TIME)) FROM mytable) >= 3 THEN to_char(TIME, 'yyyy') ELSE to_char(TIME, 'yyyy-mm') END AS season, COUNT(*) FROM mytable GROUP BY season ORDER BY season; |
(与许多其他DBMS不同,PostgreSQL允许在