2

したがって、1時間ごとの統計の健全なテーブルがあり、単一の日時として保持されるのではなく、曜日と時刻が分割されます。

+-------+-------------+------------+----------+
| 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');    

..上記のデータセットの最初の4行を返します。

+-------+-------------+------------+----------+---------------------+
| 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-2120:00:00から2012-02-2123: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」列)を検索していると考えるのはSEEMSですが、返される統計は、タイムゾーンが設定されていないクエリの統計とまったく同じです。何が起きてる?

4

1 に答える 1

2

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フィールドとしてまとめて保存するのがはるかに簡単になります。また、すでにMySQLDATETIME値である値に対してSTR_TO_DATEを使用する必要はありません。

于 2012-04-15T14:12:48.247 に答える