假设我在postgres中有一个只有2列的表:
ID
这是表格的{(bigint
)time
,其类型为timestamp
有没有办法如何获得按时间分组的ID BYYEAR-当时间是2005年2月18日它将适合2005年组(因此结果将是)
year number of rows
1998 2
2005 5
AND 如果结果行数小于某个数字(例如3),SQL将按月返回结果
像
这样的东西month number of rows
(February 2018) 5
(March 2018) 2
在postgres SQL中这可能是一种不错的方式吗?
答案 0 :(得分:1)
您可以使用窗口功能(与往常一样)。
我使用此表:
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)
首先,按月分组(子查询per_month
)
然后使用窗口函数(子查询with_year
)添加每年的总和
最后,使用CASE
决定您将输出哪一个,并删除DISTINCT
的重复项。
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)
答案 1 :(得分:0)
算上几年。如果它至少为3,则按年分组,否则按月分组:
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允许在GROUP BY
子句中使用别名。)