排除查询中非正规化日期以上的所有内容

时间:2011-06-30 23:39:47

标签: mysql denormalization

我对我的数据进行了非规范化(因此日期分为年,月,日和小时列) 但现在我想知道如何在某个日期之前查询所有内容。

这不起作用:

SELECT * 
FROM  `impression_stat_hour` 
WHERE doneforday =0
AND (
    YEAR <=2011
    AND MONTH <=6
    AND DAY <=30
    AND HOUR <=1
)

这实际上不会将所有记录“组合”在一起,因为我也想要它们,导致日期(例如)总是从0小时和1小时开始。

2 个答案:

答案 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)

  1. 你必须使处理关系的条件更复杂:

    AND (YEAR < 2011 OR (YEAR = 2011 
      AND (MONTH < 6 OR (MONTH = 6 
        AND (DAY < 30 OR (DAY = 30 AND HOUR <= 1))))))
    
  2. 如果将列合并回DATETIME值,然后将其与特定日期时间字面值进行比较,则可能更容易阅读:

    AND (STR_TO_DATE(CONCAT(YEAR,'-', MONTH,'-', DAY, ' ', HOUR), 
     '%Y-%m-%d %h') < '2011-06-30 02:00')
    
  3. 您还可以根据与具有单独日期时间组件的列相同的值存储一个实际DATETIME的额外列。这将允许您索引datetime列以获得更有效的查找。

    AND (complete_date < '2011-06-30 02:00')
    
  4. 我刚刚在MySQL 5.5上测试了这个,包括来自@Flimzy的答案。唯一可以使用索引的是上面的方法3,带有冗余列。