我对我的数据进行了非规范化(因此日期分为年,月,日和小时列) 但现在我想知道如何在某个日期之前查询所有内容。
这不起作用:
SELECT *
FROM `impression_stat_hour`
WHERE doneforday =0
AND (
YEAR <=2011
AND MONTH <=6
AND DAY <=30
AND HOUR <=1
)
这实际上不会将所有记录“组合”在一起,因为我也想要它们,导致日期(例如)总是从0小时和1小时开始。
答案 0 :(得分:1)
SELECT ...
WHERE
YEAR < 2011
OR (YEAR = 2011 AND MONTH < 6)
OR (YEAR = 2011 AND MONTH = 6 AND DAY < 30)
OR (YEAR = 2011 AND MONTH = 6 AND DAY = 30 AND HOUR <= 1)
或者:
SELECT ...
WHERE STR_TO_DATE(CONCAT(year,'-',month,'-',day,' ',hour,':00:00')) <= '2011-06-30 01:00:00';
后者可能要慢得多(因为它不能在各种日期列上使用索引。它也是未经测试的,因为我有权访问的唯一(古老)MySQL版本不支持STR_TO_DATE()。 / p>
答案 1 :(得分:1)
你必须使处理关系的条件更复杂:
AND (YEAR < 2011 OR (YEAR = 2011
AND (MONTH < 6 OR (MONTH = 6
AND (DAY < 30 OR (DAY = 30 AND HOUR <= 1))))))
如果将列合并回DATETIME
值,然后将其与特定日期时间字面值进行比较,则可能更容易阅读:
AND (STR_TO_DATE(CONCAT(YEAR,'-', MONTH,'-', DAY, ' ', HOUR),
'%Y-%m-%d %h') < '2011-06-30 02:00')
您还可以根据与具有单独日期时间组件的列相同的值存储一个实际DATETIME
的额外列。这将允许您索引datetime列以获得更有效的查找。
AND (complete_date < '2011-06-30 02:00')
我刚刚在MySQL 5.5上测试了这个,包括来自@Flimzy的答案。唯一可以使用索引的是上面的方法3,带有冗余列。