यदि आपके पास वास्तव में 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 Fiddle एटीएम डाउन है। समझने में सहायता के लिए यहां एक छोटा सा डेमो दिया गया है:
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;
अधिक स्पष्टीकरण और लिंक यहां:
रेल और पोस्टग्रेएसक्यूएल में टाइमज़ोन को पूरी तरह से नज़रअंदाज़ करना