我有一个表't',其中包含日期(yyyy-mm-dd),小时(1-12),分钟(00-59),ampm(a / p)和时区(pst / est)字段。
如何选择< = now()的行? (即已经发生过)
感谢您的建议!
编辑:这样做时不注意小时/分钟/ ap / tz字段:
SELECT * FROM t.date WHERE date <= now()
答案 0 :(得分:0)
这是一种方法 - 将所有秒,分钟等组合成一个日期并与NOW()
进行比较,确保您在同一时区进行比较。 (未测试的):
SELECT *
FROM t
LEFT JOIN y ON t.constant=y.constant
WHERE CONVERT_TZ(STR_TO_DATE(CONCAT(date,' ',hour,':',minute,' 'ampm),
'%Y-%m-%d %l:%i %p' ),
timezone,"SYSTEM") < NOW();
如果您的小时为01 - 12而非1-12,则在%h
中使用%l
代替STR_TO_DATE
。
STR_TO_DATE
尝试将日期和时间列合在一起并将其转换为日期。
CONVERT_TZ(...,timezone,"SYSTEM")
将此日期从timezone
列中指定的任何时区转换为系统时间。
然后将其与NOW()
进行比较,date
始终处于系统时间。
顺便说一句,也许您应该使用MySQL的date数据类型创建一个列{{1}},因为对它进行算术运算要容易得多!
作为参考,here是非常有用的mysql日期函数的摘要,您可以在这里阅读本答案中的特色。
祝你好运!答案 1 :(得分:0)
SELECT * FROM t
WHERE `date`<=DATE_SUB(curdate(), INTERVAL 1 DAY)
OR (
`date`<=DATE_ADD(curdate(), INTERVAL 1 DAY)
AND
CONVERT_TZ(CAST(CONCAT(`date`,' ',IF(`hour`=12 AND ampm='a',0,if(ampm='a',`hour`,`hour`+12)),':',`minute`,':00') AS DATETIME),'GMT',`timezone`)<=NOW()
)
date
&lt; = DATE_ [ADD | SUB](curdate(),INTERVAL 1天)的基本原理:
花哨的转换是一项相当昂贵的操作,所以我们不希望它在整个表上运行。这就是我们针对UNCHANGED date
字段(可能使用索引)进行预选的原因。在没有时区的情况下,当前时区过去的事件可能会超过一天,并且在任何时区都不可能在过去的时区中超过一天的事件。