我有一个名为task
的表:
id t_started_on t_due_on
------------------------------------------------
1 2018-01-12 10:45 AM 2018-01-12 07:45 PM
2 2018-01-18 09:15 AM 2018-01-19 07:00 PM
3 2018-01-16 02:30 AM 2018-01-22 10:30 AM
我想选择今天的日期在AM或PM的两个日期字段之间的记录。没有AM / PM我知道怎么做,但我的AM / PM要求就在那里:
除了日期比较之外,时间部分本身也应该在开始日期的时间部分和截止日期的时间部分之间。
我该怎么做?
如果当前时间戳是'2018-01-19 03:56 PM'而不是dabase中的上述数据,结果应该只有一行(2 nd 行),但我是在结果中得到两行(也就是3 rd 行)。
这是我的SQL查询
SELECT *
FROM `task`
WHERE '2018-01-19 03:56 PM' between t_started_on and t_due_on
不应包括3 rd 行,因为截止日期的时间部分早于当前时间的时间部分。
答案 0 :(得分:2)
您最好将日期存储为DATETIME
。由于您具有这些值,因此它已经显示您的数据库字段不属于date
类型,因为将此类字符串插入date
字段不会产生错误。
如果无法更改,则可以使用STR_TO_DATE
功能:
SELECT *
FROM `task`
WHERE t_status !=3
AND STR_TO_DATE('2018-01-19 03:56 PM', '%Y-%m-%d %h:%i %p') BETWEEN
STR_TO_DATE(t_started_on, '%Y-%m-%d %h:%i %p') AND
STR_TO_DATE(t_due_on, '%Y-%m-%d %h:%i %p')
但这确实是一个低劣的解决方案。
尽管如此,你期望只获得一排似乎很奇怪。当然第三行符合要求,因为开始/到期日是在你检查的日期之前/之后,不论时间部分。
在评论中,您说要使用不同的逻辑。我想猜测您想要分别比较日期和时间组件,并且两者都符合between
条件。这确实应该在问题中解释,因为目前尚未指定。
在这种情况下,您可以使用DATE_FORMAT
仅提取时间部分,并使用该部分重复该条件:
SELECT *,
STR_TO_DATE(t_started_on, '%Y-%m-%d %h:%i %p'),
STR_TO_DATE(t_due_on, '%Y-%m-%d %h:%i %p'),
STR_TO_DATE('2018-01-19 03:56 PM', '%Y-%m-%d %h:%i %p')
FROM `task`
WHERE t_status !=3
AND STR_TO_DATE('2018-01-19 03:56 PM', '%Y-%m-%d %h:%i %p') BETWEEN
STR_TO_DATE(t_started_on, '%Y-%m-%d %h:%i %p') AND
STR_TO_DATE(t_due_on, '%Y-%m-%d %h:%i %p')
AND DATE_FORMAT(STR_TO_DATE('2018-01-19 03:56 PM', '%Y-%m-%d %h:%i %p'), '%h:%i') BETWEEN
DATE_FORMAT(STR_TO_DATE(t_started_on, '%Y-%m-%d %h:%i %p'), '%h:%i') AND
DATE_FORMAT(STR_TO_DATE(t_due_on, '%Y-%m-%d %h:%i %p'), '%h:%i')
此查询将从结果中排除3 rd 行。