You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用LEAD函数获取下一日期,构建近6个月读数日期注册量统计查询

嘿,我来帮你搞定这个统计需求!根据你给出的输出格式,我假设你使用的是关系型数据库(比如PostgreSQL或MySQL),下面是针对性的SQL查询方案:

解决方案

核心思路分为三步:

  1. 生成26到31天的固定日期列表,确保哪怕某天没有注册记录也能显示0;
  2. 筛选出近6个月的注册数据,按地区(LOCALE)、月份(COMPETENCE)、读数日期(Reading_date)分组统计数量;
  3. 将固定日期列表和统计结果左连接,补全缺失日期的0值。

假设你的业务表名为 inscriptions,核心字段包括:

  • locale: 地区(如CEARA)
  • reading_date: 读数日期(日期类型,如'2024-01-26')
  • id: 注册记录唯一标识(用于统计数量)

PostgreSQL 版本查询语句

WITH date_range AS (
    -- 生成26到31的天数序列
    SELECT generate_series(26, 31) AS day
),
recent_months AS (
    -- 获取近6个月的月份标识(格式如JAN18)
    SELECT DISTINCT
        TO_CHAR(reading_date, 'MONYY') AS competence,
        locale
    FROM inscriptions
    WHERE reading_date >= CURRENT_DATE - INTERVAL '6 months'
)
SELECT
    rm.locale AS LOCALE,
    rm.competence AS COMPETENCE,
    dr.day AS "Reading_date(DAYS)",
    COALESCE(COUNT(i.id), 0) AS "INSCRIPTION (Quantity)"
FROM recent_months rm
CROSS JOIN date_range dr
LEFT JOIN inscriptions i
    ON rm.locale = i.locale
    AND TO_CHAR(i.reading_date, 'MONYY') = rm.competence
    AND EXTRACT(DAY FROM i.reading_date) = dr.day
    AND i.reading_date >= CURRENT_DATE - INTERVAL '6 months'
GROUP BY rm.locale, rm.competence, dr.day
ORDER BY rm.locale, rm.competence, dr.day;

MySQL 版本查询语句

WITH RECURSIVE date_range AS (
    -- 生成26到31的天数序列
    SELECT 26 AS day
    UNION ALL
    SELECT day + 1 FROM date_range WHERE day < 31
),
recent_months AS (
    -- 获取近6个月的月份标识(格式如JAN18)
    SELECT DISTINCT
        DATE_FORMAT(reading_date, '%b%y') AS competence,
        locale
    FROM inscriptions
    WHERE reading_date >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH)
)
SELECT
    rm.locale AS LOCALE,
    rm.competence AS COMPETENCE,
    dr.day AS `Reading_date(DAYS)`,
    COALESCE(COUNT(i.id), 0) AS `INSCRIPTION (Quantity)`
FROM recent_months rm
CROSS JOIN date_range dr
LEFT JOIN inscriptions i
    ON rm.locale = i.locale
    AND DATE_FORMAT(i.reading_date, '%b%y') = rm.competence
    AND DAY(i.reading_date) = dr.day
    AND i.reading_date >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH)
GROUP BY rm.locale, rm.competence, dr.day
ORDER BY rm.locale, rm.competence, dr.day;

关键细节说明:

  • date_range CTE:生成26到31的天数,确保每个天数都出现在结果中,哪怕没有对应注册记录;
  • recent_months CTE:提取近6个月内所有出现过的地区和月份组合,避免出现不存在的地区-月份条目;
  • COALESCE函数:把NULL(没有注册记录的日期)转换成0,完全匹配你示例中的格式;
  • 月份格式转换:用TO_CHAR(PostgreSQL)或DATE_FORMAT(MySQL)把日期转换成MONYY/%b%y格式,对应你要的JAN18样式;
  • 排序规则:最后按地区、月份、天数排序,让结果顺序和你示例一致。

如果你的业务表结构或字段名和假设的不一样,只需要调整对应的表名、字段名即可~

内容的提问来源于stack exchange,提问作者Elton Santos

火山引擎 最新活动