quarter()仅返回1–4的整数,不包含年份或日期范围;正确用法须与year()组合、group by时同时指定year和quarter,并注意时区与索引性能。

QUARTER 函数本身不能“生成报告”,它只是从日期中提取季度数字(1–4),真正驱动分析的是你如何把它和 GROUP BY、聚合函数配合使用——用错位置或忽略时区/年份边界,结果会完全失真。
QUARTER() 返回什么?别把它当时间范围函数用
QUARTER() 只返回一个整数:1 表示 1–3 月,2 表示 4–6 月,以此类推。它不关心年份,也不返回起止日期。常见错误是以为 QUARTER('2024-01-01') 能自动关联到“2024 Q1”,其实它只返回 1,丢失了年份上下文。
- 正确做法:永远和
YEAR()组合使用,比如CONCAT(YEAR(order_date), '-Q', QUARTER(order_date)) - 错误写法:
WHERE QUARTER(order_date) = 1—— 这会查出所有年份的 Q1,不是你想要的“本年度 Q1” - 注意时区:如果数据库时区和业务时区不一致,
QUARTER(NOW())可能比本地晚一个季度
按季度分组统计营收时,GROUP BY 必须包含 YEAR + QUARTER
只写 GROUP BY QUARTER(order_date) 会导致 2023 Q1 和 2024 Q1 的数据被合并成一行,报表完全不可读。
- 安全写法:
GROUP BY YEAR(order_date), QUARTER(order_date) ORDER BY YEAR(order_date), QUARTER(order_date) - 想补全缺失季度(比如某季度没订单)?纯 SQL 难以自动填充,建议在应用层补空或用 LEFT JOIN 临时表
- 性能提示:如果
order_date字段没索引,QUARTER(order_date)无法走索引,大表查询会变慢
和 DATE_SUB / CURDATE() 配合查“最近四个季度”最常用
运营最常要的是“过去四个完整季度”,不是“当前季度往前推四个月”。直接用 QUARTER() 不够,得靠日期运算锚定范围。
- 可靠逻辑:先算出本季度第一天,再用
DATE_SUB往前推三个季度起点 - 示例(MySQL):
SELECT CONCAT(YEAR(date_sub), '-Q', QUARTER(date_sub)) AS quarter_label, SUM(revenue) AS total_revenue FROM sales CROSS JOIN ( SELECT MAKEDATE(YEAR(CURDATE()), 1) + INTERVAL (QUARTER(CURDATE()) - 1) QUARTER AS q_start, DATE_SUB(MAKEDATE(YEAR(CURDATE()), 1) + INTERVAL (QUARTER(CURDATE()) - 1) QUARTER, INTERVAL 3 QUARTER) AS four_q_ago ) AS bounds WHERE order_date >= bounds.four_q_ago AND order_date - 关键点:用
和 <code> 构建左闭右开区间,避免跨季度重复或遗漏
真正卡住人的地方往往不是 QUARTER() 本身,而是忘记它剥离了年份信息,以及在 WHERE 中误用导致范围失控。季度分析的可靠性,取决于你是否显式维护了“年+季”的二维结构,而不是依赖函数返回的孤立数字。











