PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

अभी () फ़ंक्शन से घंटे घटाएं

timestamp के लिए उत्तर दें

आपको डेटा प्रकारों की प्रकृति को समझने की आवश्यकता है timestamp (timestamp without time zone ) और timestamptz (timestamp with time zone ) यदि आप नहीं करते हैं, तो इसे पहले पढ़ें:

  • रेल और पोस्टग्रेएसक्यूएल में समय क्षेत्रों को पूरी तरह से नज़रअंदाज़ करना

AT TIME ZONE निर्माण एक timestamp को बदल देता है करने के लिए timestamptz , जो लगभग निश्चित रूप से गलत कदम . है आपके मामले के लिए:

where eventtime at time zone 'CET' between '2015-06-16 06:00:00'
                                       and '2015-06-17 06:00:00'

पहले , यह प्रदर्शन को मारता है। AT TIME ZONE लागू किया जा रहा है कॉलम eventtime . पर व्यंजक को व्याख्या योग्य नहीं . बनाता है . Postgres eventtime . पर सादे अनुक्रमणिका का उपयोग नहीं कर सकते हैं . लेकिन सूचकांक के बिना भी, सारगर्भित भाव सस्ते होते हैं। प्रत्येक पंक्ति मान में हेरफेर करने के बजाय फ़िल्टर मानों को समायोजित करें।
आप कर सकते थे मेल खाने वाले एक्सप्रेशन इंडेक्स के साथ क्षतिपूर्ति करें, लेकिन यह शायद एक ग़लतफ़हमी है और वैसे भी गलत है।

उस अभिव्यक्ति में क्या होता है?

  1. AT TIME ZONE 'CET' timestamp को बदल देता है मान eventtime करने के लिए timestamptz अपने वर्तमान समय क्षेत्र के समय ऑफसेट को जोड़कर। समय क्षेत्र का उपयोग करते समय नाम (संख्यात्मक ऑफसेट या संक्षिप्त नाम नहीं), यह डीएसटी नियमों (डेलाइट सेविंग टाइम) को भी ध्यान में रखता है, इसलिए आपको "विंटर" टाइमस्टैम्प के लिए एक अलग ऑफसेट मिलता है। मूल रूप से आपको प्रश्न का उत्तर मिलता है:

    दिए गए समय क्षेत्र में दिए गए टाइमस्टैम्प के लिए संबंधित UTC टाइमस्टैम्प क्या है?

    प्रदर्शित करते समय उपयोगकर्ता के लिए परिणाम यह सत्र के वर्तमान समय क्षेत्र के लिए ऑफसेट समय के अनुसार स्थानीय टाइमस्टैम्प के रूप में स्वरूपित है। (अभिव्यक्ति में प्रयुक्त के समान हो भी सकता है और नहीं भी)।

  2. दाईं ओर के स्ट्रिंग अक्षर के पास उनके लिए कोई डेटा प्रकार नहीं है, इसलिए प्रकार अभिव्यक्ति में असाइनमेंट से लिया गया है। चूँकि वह timestamptz है अब, दोनों को timestamptz . पर डाला गया है , सत्र के वर्तमान समय क्षेत्र को मानते हुए।

    वर्तमान सत्र की समय क्षेत्र सेटिंग के लिए दिए गए टाइमस्टैम्प के लिए संबंधित UTC टाइमस्टैम्प क्या है।

    ऑफ़सेट डीएसटी नियमों के साथ भिन्न हो सकता है।

लंबी कहानी छोटी , यदि आप हमेशा एक ही समय क्षेत्र के साथ काम करें:CET या 'Europe/Berlin' - आज के टाइमस्टैम्प के लिए भी यही बात है, लेकिन ऐतिहासिक या (संभवतः) भविष्य के टाइमस्टैम्प के लिए नहीं, आप बस क्रॉफ्ट को काट सकते हैं।

दूसरी समस्या अभिव्यक्ति के साथ:<स्ट्राइक> BETWEEN timestamp के साथ लगभग हमेशा गलत होता है मूल्य। देखें:

  • तारीख विवरण के बीच ऑप्टिमाइज़ करें
  • PostgreSQL में ओवरलैपिंग दिनांक सीमाएँ ढूँढें
SELECT date_trunc('hour', eventtime) AS hour
     , count(DISTINCT serialnumber)  AS ct  -- sure you need distinct?
FROM   t_el_eventlog
WHERE  eventtime >= now()::date - interval '18 hours'
AND    eventtime <  now()::date + interval '6 hours'
AND    sourceid  =  44  -- don't quote the numeric literal
GROUP  BY 1
ORDER  BY 1;

now() SQL मानक का पोस्टग्रेज़ कार्यान्वयन है CURRENT_TIMESTAMP . दोनों timestamptz return लौटाते हैं (नहीं timestamp !). आप या तो उपयोग कर सकते हैं।
now()::date CURRENT_DATE . के बराबर है . दोनों वर्तमान समय क्षेत्र सेटिंग पर निर्भर करते हैं।

आपके पास एक सूचकांक . होना चाहिए फ़ॉर्म का:

CREATE INDEX foo ON t_el_eventlog(sourceid, eventtime)

या, केवल अनुक्रमणिका स्कैन की अनुमति देने के लिए:

CREATE INDEX foo2 ON t_el_eventlog(sourceid, eventtime, serialnumber)

यदि आप अलग-अलग समय क्षेत्रों में काम करते हैं, तो चीजें अधिक जटिल हो जाती हैं और आपको timestamptz . का उपयोग करना चाहिए हर चीज के लिए।

timestamptz . के लिए वैकल्पिक

प्रश्न अद्यतन से पहले, ऐसा लग रहा था कि समय क्षेत्र मायने रखता है। विभिन्न समय क्षेत्रों के साथ काम करते समय, "आज" वर्तमान समय क्षेत्र की एक कार्यात्मक निर्भरता है। लोग इसे भूल जाते हैं।

सत्र की वर्तमान समय क्षेत्र सेटिंग के साथ काम करने के लिए, ऊपर के समान क्वेरी का उपयोग करें। यदि किसी भिन्न समय क्षेत्र में निष्पादित किया जाता है, तो परिणाम वास्तविकता में गलत होते हैं। (उपरोक्त पर भी लागू होता है।)

किसी दिए गए समय क्षेत्र (आपके मामले में 'यूरोप/बर्लिन') के लिए एक सही परिणाम की गारंटी के लिए, सत्र की वर्तमान समय क्षेत्र सेटिंग की परवाह किए बिना, इसके बजाय इस अभिव्यक्ति का उपयोग करें:

    ((now() AT TIME ZONE 'Europe/Berlin')::date - interval '18 hours')
            AT TIME ZONE 'Europe/Berlin'  -- 2nd time to convert back

ध्यान रखें कि AT TIME ZONE निर्माण रिटर्न timestamp timestamptz . के लिए इनपुट और इसके विपरीत।

जैसा कि शुरुआत में बताया गया है, यहां सभी रक्तरंजित विवरण:

  • रेल और पोस्टग्रेएसक्यूएल में टाइम ज़ोन को पूरी तरह नज़रअंदाज़ करना


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. रूपांतरण टाइप करें। C में libpq में PostgreSQL OID मान के साथ मैं क्या करूँ?

  2. plpgsql चर का उपयोग करके n_distinct सेट करते समय त्रुटि

  3. PostgreSQL - तालिका नाम के रूप में गतिशील मान

  4. पोस्टग्रेज में सिंगल यूजर मोड में टेबल बनाना

  5. psycopg2 mysqldb.escape_string के बराबर है?