星期计算函数是什么
取星期序号用来判断工作日与周末。麻烦在于编号体系不统一:MySQL 的 DAYOFWEEK 里周日是 1、WEEKDAY 里周一是 0;PostgreSQL 的 DOW 里周日是 0、ISODOW 里周一是 1。混用是最经典的 bug 来源之一。
基本信息
| MySQL DAYOFWEEK | 1 是周日,7 是周六 |
|---|---|
| MySQL WEEKDAY | 0 是周一,6 是周日 |
| MySQL DAYNAME | 返回英文星期名,例如 Saturday |
| PostgreSQL DOW | 0 是周日,6 是周六 |
| PostgreSQL ISODOW | 1 是周一,7 是周日(ISO 8601) |
| 推荐做法 | 统一按 ISO 编号表达,跨库时歧义最小 |
MySQL 写法
MySQL 写法
SELECT DAYOFWEEK('2024-06-01'); -- 7(1=周日 … 7=周六)
SELECT WEEKDAY('2024-06-01'); -- 5(0=周一 … 6=周日)
SELECT DAYNAME('2024-06-01'); -- 'Saturday'
-- 筛选周末订单
SELECT * FROM orders WHERE WEEKDAY(created_at) IN (5, 6);
-- 提醒:对列做函数过滤用不上索引,大表上改成时间范围条件PostgreSQL 写法
PostgreSQL 写法
SELECT EXTRACT(DOW FROM DATE '2024-06-01'); -- 6(0=周日 … 6=周六)
SELECT EXTRACT(ISODOW FROM DATE '2024-06-01'); -- 6(1=周一 … 7=周日)
SELECT to_char(DATE '2024-06-01', 'Day'); -- 'Saturday'
-- 筛周末用 ISODOW 更直观
SELECT * FROM orders WHERE EXTRACT(ISODOW FROM created_at) IN (6, 7);编号对照
| 函数 | 周日 | 周一 | 周六 |
|---|---|---|---|
| MySQL DAYOFWEEK | 1 | 2 | 7 |
| MySQL WEEKDAY | 6 | 0 | 5 |
| PostgreSQL DOW | 0 | 1 | 6 |
| PostgreSQL ISODOW | 7 | 1 | 6 |
| ISO 8601(推荐心智模型) | 7 | 1 | 6 |
| MySQL DAYNAME | Sunday | Monday | Saturday |
典型使用场景
- 统计工作日与周末的业务量差异
- 排班表:判断某天是否需要值班
- 结算规则:按自然日还是工作日计算账期
- 流量分析:找出周末的峰值时段
- 数据校验:确认日期字段对应的星期是否合理
- 跨系统报表对齐:核对同一日期是否归到同一天
- 账单周期:按周聚合时确定每周的起止日
- 告警降噪:把周末的异常告警单独归类,避免误判为故障
同一句“周六等于 6”在不同体系里含义不同:MySQL 的 WEEKDAY 与 PostgreSQL 的 ISODOW 都以周一为基准,而 DAYOFWEEK 与 DOW 用的是另一套。跨库脚本最好把编号含义写进注释,避免后来人改错。
按周聚合时先确定周起点:ISO 周从周一开始,北美习惯从周日开始,两者在同一份数据上会得到不同的周汇总。报表口径里要写明用的是哪一种。
对列做 EXTRACT 或 WEEKDAY 过滤无法使用索引:按天或按周筛选时改成时间范围条件(大于等于起点、小于终点),既走索引也避开时区歧义。