実際にタイプtimestamp
の列がある場合 現在のタイムゾーンに応じて(部分的に)解釈します。このタイムゾーンは異なる可能性があるため、インデックスは通常不可能です。 。 IMMUTABLE
でのみインデックスを作成できます データ...
更新後:
これらの質問に答えるには:
- 「今日」から始まる予約は何ですか?
- 将来の開始日はどの予約ですか?
- 過去に開始日が設定されている予約は何ですか?
... timestamp with time zone
。ただのdate
十分に正確ではありません。
ローカルの「今日」(現在のタイムゾーンで定義)のみに関心がある限り )、しません タイムゾーンを明示的に保存する必要があります。世界のどこで発生するかは気にせず、比較するのに絶対的な時間が必要なだけです。
次に、「今日」から予約を取得するには、次のようにします。
SELECT *
FROM reservations
WHERE start_on::date = current_date;
ただし、これは引数不可
です。 start_on::date
は派生式であり、式は現在のタイムゾーンに依存し、IMMUTABLE
ではないため、(ダーティトリックなしで)このための関数インデックスを作成することもできません。 。
代わりに 、UTC時間の「私たちの」日の開始と終了と比較してください:
SELECT *
FROM reservations
WHERE start_on >= current_date::timestamptz
AND start_on < (current_date + 1)::timestamptz; -- exclude upper border
これで、この単純なインデックスはクエリをサポートできます:
CREATE INDEX ON reservations (start_on);
デモ
SQLフィドルはATMをダウンしています。理解に役立つ小さなデモを次に示します。
CREATE TEMP TABLE reservations (
reservation_id serial
, start_on timestamptz NOT NULL
, time_zone text); -- we don't need this
INSERT INTO reservations (start_on, time_zone) VALUES
('2014-04-09 01:00+02', 'Europe/Vienna')
, ('2014-04-09 23:00+02', 'Europe/Vienna')
, ('2014-04-09 01:00+00', 'UTC') -- the value is independent of the time zone
, ('2014-04-09 23:00+00', 'UTC') -- only display depends on current time zone
, ('2014-04-09 01:00-07', 'America/Los_Angeles')
, ('2014-04-09 23:00-07', 'America/Los_Angeles');
SELECT start_on, time_zone
, start_on::timestamp AS local_ts
, start_on AT TIME ZONE time_zone AS ts_at_tz
, current_date::timestamptz AS lower_bound
, (current_date + 1)::timestamptz AS upper_bound
FROM reservations
WHERE start_on >= current_date::timestamptz
AND start_on < (current_date + 1)::timestamptz;
詳細な説明とリンクはこちら:
RailsとPostgreSQLでタイムゾーンを完全に無視する