sql server中datepart(weekday,@date)结果依赖datefirst设置,稳妥做法是显式set datefirst 7或用应用层判断;mysql推荐weekday()(0=周一);postgresql应使用extract(isodow from ...)(1=周一)。

SQL Server里用DATEPART判断周末要小心默认设置
DATEPART(weekday, @date)返回的数字依赖于当前会话的DATEFIRST设置,默认是7(周日为第一天),此时周六=7、周日=1。直接写DATEPART(weekday, col) IN (1, 7)看似合理,但一旦数据库或连接设置了SET DATEFIRST 1(周一为第一天),结果就全乱了。
稳妥做法是显式指定基准:
- 先执行
SET DATEFIRST 7统一上下文(适合单条语句或存储过程开头) - 或改用
DATEPART(weekday, DATEADD(day, 1 - DATEPART(weekday, @date), @date))这类偏移计算(不推荐,难读) - 更推荐:用
DATEPART(dw, @date)配合SET DATEFIRST 7,并加注释说明依据
MySQL用WEEKDAY()比DAYOFWEEK()更直观
WEEKDAY()返回0(周一)到6(周日),周末就是5和6;而DAYOFWEEK()返回1(周日)到7(周六),周末是1和7——容易记混。
实际判断时优先选WEEKDAY():
-
WHERE WEEKDAY(order_date) IN (5, 6)—— 清晰对应周六、周日 - 避免用
DAYOFWEEK()除非业务逻辑明确要求周日为第1天 - 注意:
WEEKDAY()不受default_week_format影响,行为稳定
PostgreSQL没有内置WEEKDAY,但EXTRACT(ISODOW FROM ...)最可靠
PostgreSQL用EXTRACT(DOW FROM col)返回0(周日)到6(周六),但ISO标准是ISODOW:1(周一)到7(周日),周末是6和7。
所以判断周末必须用ISODOW:
WHERE EXTRACT(ISODOW FROM order_date) IN (6, 7)- 别用
DOW,否则IN (0, 6)看似对,实则把周日当天算进“周末”却漏掉周一前的周六(取决于查询时间范围) - 如果表里存的是
timestamptz,确保时区一致,否则EXTRACT按服务器时区计算
跨数据库写法?别硬凑,用应用层判断更稳
试图用CASE WHEN嵌套不同函数模拟统一接口,最终只会让SQL臃肿且难调试。比如在ORM里拼条件,或在应用代码中解析日期再过滤。
真正需要跨库时:
- 在DAO层封装
isWeekend(date)方法,各数据库走各自最优函数 - 若必须SQL内处理,优先选目标库最直白的函数,而不是迁就“看起来一样”
- 特别注意:Hive/Spark SQL的
dayofweek()返回1(周日)到7(周六),和MySQL的DAYOFWEEK()一致,但和WEEKDAY()相反
日期函数的语义差异比字符串函数更隐蔽,同一串SQL在不同库跑出不同结果,往往就卡在这一位数字上。










