PostgreSQL 中使用CTE获取时间段数据的技巧

在 PostgreSQL 中,同样可以使用 CTE(公共表表达式)来获取特定时间段的数据。PostgreSQL 提供了丰富的日期和时间函数,结合这些函数,能够轻松生成最近的月份、周、季度等时间段。下面是如何在 PostgreSQL 中获取最近十二个月、最近十二周、最近四个季度,以及十二个月前的月第一天和十二周前的周第一天的示例。

1. 获取最近十二个月

在 PostgreSQL 中,可以使用 TO_CHAR 函数结合递归CTE来生成最近十二个月的列表。

sql 复制代码
WITH RECURSIVE last_twelve_months AS (
    SELECT 
        TO_CHAR(CURRENT_DATE, 'YYYY-MM') AS year_month,
        CURRENT_DATE::DATE AS date_value
    UNION ALL
    SELECT 
        TO_CHAR(date_value - INTERVAL '1 MONTH', 'YYYY-MM'),
        (date_value - INTERVAL '1 MONTH')::DATE
    FROM last_twelve_months
    WHERE date_value > CURRENT_DATE - INTERVAL '11 MONTH'
)
SELECT year_month
FROM last_twelve_months
ORDER BY year_month DESC;

获取最近十二周

sql 复制代码
WITH RECURSIVE last_twelve_weeks AS (
    SELECT 
        TO_CHAR(DATE_TRUNC('week', CURRENT_DATE), 'YYYY-MM-DD') AS week_start,
        DATE_TRUNC('week', CURRENT_DATE)::DATE AS date_value
    UNION ALL
    SELECT 
        TO_CHAR(DATE_TRUNC('week', date_value - INTERVAL '1 WEEK'), 'YYYY-MM-DD'),
        DATE_TRUNC('week', date_value - INTERVAL '1 WEEK')::DATE
    FROM last_twelve_weeks
    WHERE date_value > CURRENT_DATE - INTERVAL '11 WEEK'
)
SELECT week_start
FROM last_twelve_weeks
ORDER BY week_start DESC;

获取最近四个季度

sql 复制代码
WITH RECURSIVE last_four_quarters AS (
    SELECT 
        EXTRACT(YEAR FROM CURRENT_DATE) AS year,
        EXTRACT(QUARTER FROM CURRENT_DATE) AS quarter,
        CURRENT_DATE::DATE AS date_value
    UNION ALL
    SELECT 
        CASE WHEN quarter = 1 THEN year - 1 ELSE year END,
        CASE WHEN quarter = 1 THEN 4 ELSE quarter - 1 END,
        (date_value - INTERVAL '3 MONTH')::DATE
    FROM last_four_quarters
    WHERE date_value > CURRENT_DATE - INTERVAL '1 YEAR'
)
SELECT CONCAT(year, '-Q', quarter) AS year_quarter
FROM last_four_quarters
ORDER BY year DESC, quarter DESC;
  1. 获取十二个月前的月第一天
sql 复制代码
SELECT DATE_TRUNC('month', CURRENT_DATE - INTERVAL '12 MONTH') AS first_day_of_month;
  1. 获取十二周前的周第一天
sql 复制代码
SELECT DATE_TRUNC('week', CURRENT_DATE - INTERVAL '12 WEEK') AS first_day_of_week;

测试和调试

  • 确保在执行这些查询之前,检查 PostgreSQL 的版本,因为有些功能(如递归 CTE)在非常旧的版本中可能不支持。
  • 如果仍然无法正确获取数据,可以逐步调试,如单独运行每一部分的查询,检查 CURRENT_DATE、INTERVAL 的使用是否正确。
  • 还可以直接使用 NOW() 替代 CURRENT_DATE 来确保取到的是完整的时间戳数据。
相关推荐
白帽攻防录30 分钟前
SRC 挖洞:Roundcube 预认证 SQL 注入深度复盘,CVE-2026-48842 preg_replace 转义绕过怎么打穿邮件系统
网络·数据库·sql·网络安全·sql注入
꯭自꯭闭꯭1 小时前
达梦SQL优化相关
linux·运维·数据库·sql
对空六课1 小时前
支持注意力分析的热力图工具有哪些?
前端·数据库·数据分析
南京码讯光电技术有限公司2 小时前
How to Design an Antenna System for an Industrial WiFi Module
数据库·人工智能
lusklusklusk3 小时前
Oracle数据库基础之2_体系结构
数据库·oracle
可乐ea3 小时前
从第一性原理构建 AI Agent:提示词、工具、技能与记忆全解剖
数据库·人工智能·工具调用·ai智能体·提示词工程·agent开发·智能体记忆
东方护航数据恢复(深圳)3 小时前
医疗案例:HIS/PACS 数据库页损坏修复,医院不停诊完成恢复【东方护航数据恢复深圳店】
数据库·数据恢复·医疗·二次开盘
lusklusklusk4 小时前
Oracle数据库基础之11_Duplicate和Dataguard和RAC
数据库·oracle
PHP实战开发录6 小时前
MySQL字段加索引为什么没变快
数据库·mysql·php·开发
红红谈说7 小时前
标签化推送与已读统计怎么做?一次通知链路的工程复盘
数据库·消息推送·数字乡村·集合运算·已读回执·标签体系·写入放大