DAYNAME()在MySQL中返回固定英文星期名,不支持数字或中文;PostgreSQL需用TO_CHAR(col,'FMDay'),SQLite须用strftime()配合CASE映射,跨库应统一用数字函数如WEEKDAY()/EXTRACT(DOW FROM ...)/strftime('%w',...)。

MySQL 中 DAYNAME() 返回的是英文星期名,不是数字
很多人用 DAYNAME() 是想判断“今天是不是周日”,结果发现返回 'Monday' 这种字符串,没法直接和数字 0–6 比较。它只做一件事:把日期转成本地化(但实际是固定英文)的星期名称,不支持格式控制,也不受 lc_time_names 影响(除非你显式设了,且 MySQL 版本 ≥ 5.7.14)。
常见错误现象:WHERE DAYNAME(date_col) = 0 直接报错或永远不匹配;或者误以为 DAYNAME('2024-01-01') 会返回 '周一',其实固定返回 'Monday'。
- 如果要数字(比如周一=1,周日=7),改用
WEEKDAY()(周一=0)或DAYOFWEEK()(周日=1) -
DAYNAME()的参数必须是合法日期类型,传入NULL或非法字符串(如'2024-13-01')会返回NULL,不报错但容易漏数据 - 在 WHERE 条件里用
DAYNAME(col) = 'Sunday'可以,但性能差——无法走索引,建议提前计算好并存为冗余字段或用生成列
PostgreSQL 没有 DAYNAME(),得用 TO_CHAR()
直接写 DAYNAME(date_col) 在 PostgreSQL 里会报错:ERROR: function dayname(timestamp without time zone) does not exist。它不用函数名映射,而是靠格式化模板。
正确做法是用 TO_CHAR(date_col, 'Day')(注意首字母大写,带空格补位)或更干净的 TO_CHAR(date_col, 'FMDay')(FM 去掉尾部空格)。
-
TO_CHAR(col, 'D')返回数字(周日=1),但受lc_time和datestyle影响,行为不稳定,别依赖 - 想跨数据库兼容?别硬套函数名,统一用
EXTRACT(DOW FROM col)(PostgreSQL)对应 MySQL 的DAYOFWEEK(col)-1,都是周日=0、周六=6 - 如果输出要中文,PostgreSQL 需配合
lc_time设置为'zh_CN.UTF-8',且TO_CHAR(col, 'FMDay')才显示'星期一';否则仍是英文
SQLite 里根本没 DAYNAME(),得手拼或用 strftime()
SQLite 不提供 DAYNAME(),调用就报 no such function: DAYNAME。它的日期函数全靠 strftime() 模板驱动。
正确写法是:strftime('%w', date_col) 得数字(周日=0),strftime('%W', date_col) 是全年第几周,而星期名要用 strftime('%W', ...) 不行——得自己映射:
SELECT CASE strftime('%w', '2024-01-01')
WHEN '0' THEN 'Sunday'
WHEN '1' THEN 'Monday'
-- ... 全写完
END;
- 别用
strftime('%d', ...)想取星期名,那是“月几号” -
strftime()输入必须是能被识别的日期字符串(如'2024-01-01'或datetime('now')),传 UNIX 时间戳要先转:strftime('%w', datetime(unix_ts, 'unixepoch')) - 如果只是过滤“周五的数据”,用
strftime('%w', col) = '5'比拼字符串快,也避免本地化问题
跨数据库写 SQL 时,DAYNAME() 是最不兼容的函数之一
MySQL 有,PostgreSQL 没,SQLite 没,SQL Server 用 DATENAME(WEEKDAY, ...),Oracle 用 TO_CHAR(..., 'DAY')。名字不同、返回格式不同、首字母大小写和空格处理也不同。
真要兼容,要么在应用层处理,要么统一用数字型函数(如 WEEKDAY() / EXTRACT(DOW FROM ...) / strftime('%w', ...)),再映射成业务需要的名称。
- 别在视图或存储过程中硬写
DAYNAME(),除非确定只跑 MySQL - ORM 如 Django 或 SQLAlchemy 默认不封装
DAYNAME(),生成的 SQL 会直接暴露方言差异 - 测试时最容易忽略的点:同一条 SQL 在本地 SQLite(开发)和线上 MySQL(生产)行为不一致,尤其涉及排序或分组时










