MySQL中WEEKDAY()返回周一0至周日6,周末为5和6,可用WHERE WEEKDAY(date) NOT IN (5,6)过滤;PostgreSQL用EXTRACT(DOW FROM date)返回周日0至周六6,周末为0和6;SQL Server需先SET DATEFIRST 1再用DATEPART(WEEKDAY,date) NOT IN (6,7)。

MySQL 中用 WEEKDAY() 判断是否为周末
MySQL 默认周一是 0、周日是 6,所以周末是 5(周六)和 6(周日)。直接在 WHERE 中排除即可:
SELECT * FROM orders WHERE WEEKDAY(order_date) NOT IN (5, 6);
注意:WEEKDAY() 返回的是基于周一为 0 的整数,不受 SET lc_time_names 或时区影响,比 DAYOFWEEK() 更稳定。如果表数据量大,这个字段最好加索引——但函数会阻止索引使用,所以更优解是加一个生成列或提前算好 weekday 值存为普通字段。
PostgreSQL 中用 EXTRACT(DOW FROM ...) 过滤周六日
PostgreSQL 的 DOW(Day of Week)定义是周日 = 0,周六 = 6,因此周末是 0 和 6:
SELECT * FROM events WHERE EXTRACT(DOW FROM event_time) NOT IN (0, 6);
常见错误是照搬 MySQL 逻辑写成 NOT IN (5,6),结果把周日(0)漏掉了。另外,EXTRACT 在 WHERE 中同样无法走索引;若查询频繁,建议建表达式索引:CREATE INDEX idx_events_dow ON events (EXTRACT(DOW FROM event_time));
SQL Server 中用 DATEPART(WEEKDAY, ...) 需先确认 DATEFIRST
SQL Server 的 DATEPART(WEEKDAY, ...) 返回值依赖服务器级设置 DATEFIRST(默认为 7,即周日=1),这意味着周末可能是 1 和 7,也可能是其他组合。最安全的做法是显式设置:
SET DATEFIRST 1; -- 强制周一为第一天(周一=1,周日=7) SELECT * FROM logs WHERE DATEPART(WEEKDAY, created_at) NOT IN (6, 7);
如果不改 DATEFIRST,又想兼容默认配置,可改用 DATEPART(WEEKDAY, ...)+@@DATEFIRST-1)%7 归一化,但太绕;实际项目中更推荐统一设为 SET DATEFIRST 1 后再查,避免隐式行为。
跨数据库可移植的写法:用 TO_CHAR 或字符串提取(Oracle / PostgreSQL)
Oracle 和较新版本 PostgreSQL 支持 TO_CHAR(date_col, 'D'),返回本地化周几编号(受 NLS_TERRITORY 或 lc_time 影响),不可靠;更稳妥的是用 TO_CHAR(..., 'FMDAY') 提取英文全名再匹配:
-- PostgreSQL / Oracle 兼容写法(性能稍差,但语义清晰)
SELECT * FROM sales
WHERE LOWER(TO_CHAR(sale_date, 'FMDAY')) NOT IN ('saturday', 'sunday');这种写法不依赖数字编号规则,可读性强,适合需要跨库或对日期逻辑特别敏感的场景。缺点是无法利用索引,且 TO_CHAR 在大数据集上开销明显高于数值判断。
真正麻烦的不是语法,而是不同数据库对“周几=几”的默认定义不一致,以及函数是否能走索引——别只盯着怎么写对,先确认你的数据库当前 DATEFIRST 或 lc_time 是什么,再决定要不要固化规则。

















