从Drupal数据库用户表取数据:MySQL查询无结果问题排查
问题分析与解决方案
你的查询语句没返回结果的核心问题是时间字符串的格式解析错误,导致生成的UNIX时间戳不符合预期,和数据库中created字段的值不匹配。下面逐条分析并修正:
第一条查询的问题
SELECT * FROM users WHERE `created` BETWEEN UNIX_TIMESTAMP(STR_TO_DATE('March 31 2017 00:00AM', '%M %d %Y %h:%i%p')) AND UNIX_TIMESTAMP(STR_TO_DATE('March 31 2017 12:00PM', '%M %d %Y %h:%i%p'))
这里的问题出在时间格式符和时间字符串的匹配上:
%h是12小时制的小时格式,范围是1-12,但你写的00:00AM里的00不符合这个范围,MySQL无法正确解析这个时间,会返回NULL,最终UNIX_TIMESTAMP(NULL)也是NULL,导致整个BETWEEN条件失效。
修正方法:把午夜时间改成12:00AM适配12小时制格式,或者改用24小时制的%H格式:
-- 方案1:用12小时制的正确午夜格式 SELECT * FROM users WHERE `created` BETWEEN UNIX_TIMESTAMP(STR_TO_DATE('March 31 2017 12:00AM', '%M %d %Y %h:%i%p')) AND UNIX_TIMESTAMP(STR_TO_DATE('March 31 2017 12:00PM', '%M %d %Y %h:%i%p')); -- 方案2:改用24小时制格式符%H SELECT * FROM users WHERE `created` BETWEEN UNIX_TIMESTAMP(STR_TO_DATE('March 31 2017 00:00', '%M %d %Y %H:%i')) AND UNIX_TIMESTAMP(STR_TO_DATE('March 31 2017 12:00', '%M %d %Y %H:%i'));
第二条查询的问题
SELECT users.name AS users_name, users.uid AS uid, users.mail AS users_mail, users.created AS users_created FROM users as users WHERE users.created BETWEEN UNIX_TIMESTAMP( ( 'Mar 31 2017 00:00:00' ) ) AND UNIX_TIMESTAMP( ( 'April 1 2017 00:00:00' ) ) ORDER BY users_created ASC
这里的问题是直接把缩写月份的字符串'Mar 31 2017 00:00:00'传给UNIX_TIMESTAMP(),MySQL的自动日期解析不一定能识别这种缩写格式(依赖于数据库的时区和语言设置),导致解析失败返回NULL,同样让条件失效。
修正方法:用STR_TO_DATE()指定正确的格式符%b(缩写月份)来解析字符串:
SELECT users.name AS users_name, users.uid AS uid, users.mail AS users_mail, users.created AS users_created FROM users as users WHERE users.created BETWEEN UNIX_TIMESTAMP(STR_TO_DATE('Mar 31 2017 00:00:00', '%b %d %Y %H:%i:%s')) AND UNIX_TIMESTAMP(STR_TO_DATE('April 1 2017 00:00:00', '%b %d %Y %H:%i:%s')) ORDER BY users_created ASC;
额外验证技巧
你可以单独运行时间解析的部分,确认生成的UNIX时间戳是否正确:
-- 测试第一条语句的时间解析 SELECT UNIX_TIMESTAMP(STR_TO_DATE('March 31 2017 00:00AM', '%M %d %Y %h:%i%p')); -- 会返回NULL,说明解析失败 SELECT UNIX_TIMESTAMP(STR_TO_DATE('March 31 2017 12:00AM', '%M %d %Y %h:%i%p')); -- 返回正确的时间戳 -- 测试第二条语句的时间解析 SELECT UNIX_TIMESTAMP('Mar 31 2017 00:00:00'); -- 可能返回NULL或错误值 SELECT UNIX_TIMESTAMP(STR_TO_DATE('Mar 31 2017 00:00:00', '%b %d %Y %H:%i:%s')); -- 返回正确的时间戳
另外,如果你不确定数据库中created字段的时间范围,可以先查询几条记录确认:
SELECT uid, name, created, FROM_UNIXTIME(created) FROM users LIMIT 5;
这样能直观看到created对应的日期时间,方便你调整查询的时间范围。
内容的提问来源于stack exchange,提问作者Ashish Patel
相关产品推荐
相关产品推荐

