PostgreSQL中如何选择并按双周分组数据?
嘿,我完全懂你的困扰——PostgreSQL确实没提供直接的fortnight日期参数,但咱们用点简单的数学计算就能搞定双周分组,效果一模一样!
核心思路其实很简单:双周就是每14天为一组,我们可以基于现有日期函数的结果做除法取整,生成唯一的双周分组标识,再结合年份就能避免跨年的分组混乱。
给你两种实用的改写方案:
方案一:基于ISO周数计算
PostgreSQL的date_part('week', dt)会返回ISO标准的周数(一年最多53周),我们把周数除以2取整,就能得到双周的分组编号:
SELECT AVG((f1+f2+f3+f4)/4) as fld_avg FROM ( SELECT date_part('year', dt) AS year_part, -- 用周数除以2取整,生成双周组编号 floor(date_part('week', dt) / 2) AS fortnight_part, f1, f2, f3, f4 FROM foo WHERE dt >= date_trunc('day', NOW() - '3 month') ) foo GROUP BY year_part, fortnight_part
这个方法的好处是遵循ISO周的规则,自动处理跨年的边界情况,不会把上一年最后一周和当年第一周的双周合并。
方案二:基于一年中的天数计算
如果更习惯从每年1月1日开始计算双周,可以用一年中的天数(doy)除以14取整:
SELECT AVG((f1+f2+f3+f4)/4) as fld_avg FROM ( SELECT date_part('year', dt) AS year_part, -- 一年中的天数除以14,得到从年初开始的双周组编号 floor(date_part('doy', dt) / 14) AS fortnight_part, f1, f2, f3, f4 FROM foo WHERE dt >= date_trunc('day', NOW() - '3 month') ) foo GROUP BY year_part, fortnight_part
进阶:显示双周起始日期(更直观)
如果不想用编号,想直接在结果里看到每个双周的起始日期,可以这样写:
SELECT -- 生成双周的起始日期(这里以ISO周的周一为双周起点) date_trunc('week', dt) - CASE WHEN date_part('week', dt) % 2 = 0 THEN '7 days'::interval ELSE '0 days'::interval END AS fortnight_start, AVG((f1+f2+f3+f4)/4) as fld_avg FROM foo WHERE dt >= date_trunc('day', NOW() - '3 month') GROUP BY fortnight_start ORDER BY fortnight_start
这样结果里会清晰显示每个分组对应的双周起始时间,比编号更容易理解。
内容的提问来源于stack exchange,提问作者Homunculus Reticulli
相关产品推荐
相关产品推荐

