开发者

Excluding everything above denormalized date in query

开发者 https://www.devze.com 2023-03-16 09:34 出处:网络
I denormalized my data (so a date is split up in a year, month, day and hour column) But now I wonder how to query everything before a certain date.

I denormalized my data (so a date is split up in a year, month, day and hour column) But now I wonder how to query everything before a certain date.

This does NOT work:

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

This won't actually "group" all the records together as I want them too, resulting in date that is (for examp开发者_JAVA技巧le) always from hour 0 and hour 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)

Or:

SELECT ...
WHERE STR_TO_DATE(CONCAT(year,'-',month,'-',day,' ',hour,':00:00')) <= '2011-06-30 01:00:00';

The latter is probably a lot slower (since it can't use indexes on your various date columns. It's also untested, since the only (ancient) version of MySQL I have access to doesn't support STR_TO_DATE().


  1. You'd have to make the condition be more complex to handle ties:

    AND (YEAR < 2011 OR (YEAR = 2011 
      AND (MONTH < 6 OR (MONTH = 6 
        AND (DAY < 30 OR (DAY = 30 AND HOUR <= 1))))))
    
  2. It's probably easier to read if you combine the columns back into a DATETIME value and then compare that to a specific datetime literal:

    AND (STR_TO_DATE(CONCAT(YEAR,'-', MONTH,'-', DAY, ' ', HOUR), 
     '%Y-%m-%d %h') < '2011-06-30 02:00')
    
  3. You could also store an extra column that is an actual DATETIME based on the same value as that of the columns with separate datetime components. That would allow you to index the datetime column for more efficient lookups.

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

I just tested this on MySQL 5.5, including the answer from @Flimzy. The only one that can use an index is my method 3 above, with the redundant column.

0

精彩评论

暂无评论...
验证码 换一张
取 消