1

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

这不起作用:

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

这实际上不会像我想要的那样将所有记录“分组”在一起,从而导致日期(例如)总是从 0 小时到 1 小时。

4

2 回答 2

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()。

于 2011-06-30T23:58:05.213 回答
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基于与具有单独日期时间组件的列相同的值的实际值。这将允许您索引日期时间列以进行更有效的查找。

    AND (complete_date < '2011-06-30 02:00')
    

我刚刚在 MySQL 5.5 上对此进行了测试,包括来自@Flimzy 的答案。唯一可以使用索引的是我上面的方法 3,带有冗余列。

于 2011-07-01T00:01:06.933 回答