mysql: convert_tz игнорируется в сравнении предложений where? - PullRequest
2 голосов
/ 07 марта 2012

Итак, у меня есть здоровая таблица почасовой статистики, в которой день и время разделены, а не хранятся как единое время:

+-------+-------------+------------+----------+
| cakes | pies        | day        | hour     |
+-------+-------------+------------+----------+
|     1 |          28 | 2012-02-21 |       20 |
|     0 |          14 | 2012-02-21 |       21 |
|     1 |          15 | 2012-02-21 |       22 |
|     1 |          11 | 2012-02-21 |       23 |
|     0 |           7 | 2012-02-22 |        0 |
|     0 |           9 | 2012-02-22 |        1 |
|     0 |           5 | 2012-02-22 |        2 |
|     0 |           8 | 2012-02-22 |        3 |
|     1 |          11 | 2012-02-22 |        4 |
|     0 |          11 | 2012-02-22 |        5 |
|     0 |          12 | 2012-02-22 |        6 |
|     1 |          19 | 2012-02-22 |        7 |
|     0 |          26 | 2012-02-22 |        8 |
|     0 |          20 | 2012-02-22 |        9 |
|     0 |          24 | 2012-02-22 |       10 |
|     2 |          26 | 2012-02-22 |       11 |
|     1 |          22 | 2012-02-22 |       12 |
|     1 |          24 | 2012-02-22 |       13 |
|     1 |          32 | 2012-02-22 |       14 |
|     0 |          25 | 2012-02-22 |       15 |
|     2 |          20 | 2012-02-22 |       16 |
|     0 |          24 | 2012-02-22 |       17 |
|     1 |          24 | 2012-02-22 |       18 |
|     0 |          15 | 2012-02-22 |       19 |
+-------+-------------+------------+----------+

Я хочу делать выборки с учетом часового пояса из этой таблицы, чтобы люди во всем мире могли знать о моих квотах на торт или пирог в любое время.

Вот мой запрос без преобразования часового пояса:

select cakes, pies, day, hour, 
    str_to_date(concat(day,' ',hour,':00'), '%Y-%m-%d %H:%i:%s') 'this' from stats where 
    str_to_date(concat(day,' ',hour,':00'), '%Y-%m-%d %H:%i:%s') between 
    str_to_date('2012-02-21 20:00:00', '%Y-%m-%d %H:%i:%s') and 
    str_to_date('2012-02-21 23:00:00', '%Y-%m-%d %H:%i:%s');    

.. которая возвращает первые четыре строки набора данных выше:

+-------+-------------+------------+----------+---------------------+
| cakes | pies        | day        | hour     | this                |
+-------+-------------+------------+----------+---------------------+
|     1 |          28 | 2012-02-21 |       20 | 2012-02-21 20:00:00 |
|     0 |          14 | 2012-02-21 |       21 | 2012-02-21 21:00:00 |
|     1 |          15 | 2012-02-21 |       22 | 2012-02-21 22:00:00 |
|     1 |          11 | 2012-02-21 |       23 | 2012-02-21 23:00:00 |
+-------+-------------+------------+----------+---------------------+

Пока все хорошо. Теперь мне нужно сделать это с учетом часового пояса. Допустим, мой сервер находится в Калифорнии, а кто-то в Новой Зеландии в дневное время пытается получить доступ к моей статистике тортов и пирогов с 2012-02-21 с 20:00:00 до 2012-02-21 23: 00: 00:

select cakes, pies, day, hour, 
    str_to_date(convert_tz(concat(day,' ',hour,':00'), '+13:00','-8:00'), '%Y-%m-%d %H:%i:%s') 'this' from stats where
    str_to_date(convert_tz(concat(day,' ',hour,':00'), '+13:00','-8:00'), '%Y-%m-%d %H:%i:%s') between 
    str_to_date(convert_tz('2012-02-21 20:00:00', '+13:00','-8:00') , '%Y-%m-%d %H:%i:%s') and 
    str_to_date(convert_tz('2012-02-21 23:00:00', '+13:00','-8:00') , '%Y-%m-%d %H:%i:%s');

Но вот где это становится странным:

+-------+-------------+------------+----------+---------------------+
| cakes | pies        | day        | hour     | this                |
+-------+-------------+------------+----------+---------------------+
|     1 |          28 | 2012-02-21 |       20 | 2012-02-20 23:00:00 |
|     0 |          14 | 2012-02-21 |       21 | 2012-02-21 00:00:00 |
|     1 |          15 | 2012-02-21 |       22 | 2012-02-21 01:00:00 |
|     1 |          11 | 2012-02-21 |       23 | 2012-02-21 02:00:00 |
+-------+-------------+------------+----------+---------------------+   

Кажется, что он ищет откорректированные по часовому поясу значения (столбец "this"), но возвращаемая статистика точно такая же, как и в запросе без часового пояса! Что здесь происходит?

1 Ответ

2 голосов
/ 15 апреля 2012

Вы конвертируете все даты для сравнения (как даты ввода, так и даты из базы данных), используя convert_tz, поэтому не удивительно, что вы получите те же данные обратно.Я думаю, что вы, вероятно, хотите, это

SELECT cakes, pies, day, hour, 
    CONVERT_TZ(CONCAT(day,' ',hour,':00'), '+13:00','-8:00') AS 'this' 
FROM stats 
WHERE 
    CONVERT_TZ(CONCAT(day,' ',hour,':00'), '+13:00','-8:00')
        BETWEEN 
            '2012-02-21 20:00:00' 
        AND '2012-02-21 23:00:00'

Но почему вы храните дату и время отдельно?Было бы намного проще хранить ваши запросы вместе в виде поля DATETIME.Также вам не нужно использовать STR_TO_DATE для значений, которые уже являются значениями MySQL DATETIME.

...