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

उम्मीद के मुताबिक काम नहीं कर रहे चेक बाधा के आधार पर विभाजन छंटाई

आपका कॉलम created_at timestamp without time zone

लेकिन now() रिटर्न timestamp with time zone . व्यंजक now() - '1 hour'::interval timestamp [without time zone] के लिए ज़बरदस्ती किया जा रहा है , जिसमें दो समस्याएं हैं :

1.) आपने इसके लिए नहीं पूछा, लेकिन अभिव्यक्ति अविश्वसनीय है। इसका परिणाम उस सत्र की वर्तमान समय क्षेत्र सेटिंग पर निर्भर करता है जिसमें क्वेरी निष्पादित की जा रही है। यहां विवरण:

अभिव्यक्ति को स्पष्ट करने के लिए, आप इसका उपयोग कर सकते हैं:

now() AT TIME ZONE 'Europe/London' -- your time zone here

या बस (मैनुअल यहां पढ़ें) :

LOCALTIMESTAMP  -- explicitly take the local time

मैं timestamptz . के साथ काम करने पर विचार करूंगा इसके बजाय।
न तो आपकी दूसरी समस्या का समाधान करता है:

2.) आपके प्रश्न का उत्तर दें। प्रतिबंध बहिष्करण काम नहीं करता है। प्रति दस्तावेज़:

बोल्ड जोर मेरा।

now() CURRENT_TIMESTAMP . का पोस्टग्रेज कार्यान्वयन है . जैसा कि आप सिस्टम कैटलॉग में देख सकते हैं, यह केवल STABLE है , नहीं IMMUTABLE :

SELECT proname, provolatile FROM pg_proc WHERE proname = 'now';

proname | provolatile
--------+------------
now     | s              -- meaning: STABLE

समाधान

1.) आप WHERE . में एक स्थिरांक प्रदान करके सीमा को पार कर सकते हैं शर्त (जो हमेशा "अपरिवर्तनीय" होती है):

select count(*) from events
where created_at > '2015-05-25 15:49:20.037815'::timestamp;  -- derived from your example

2.) या एक अपरिवर्तनीय फ़ंक्शन को "नकली" करके:

CREATE FUNCTION f_now_immutable()
  RETURNS timestamp AS
$func$
SELECT now() AT TIME ZONE 'UTC'  -- your time zone here
$func$  LANGUAGE sql IMMUTABLE;

और फिर:

select count(*) from events
where created_at > f_now_immutable() - interval '1 hour'

हालांकि सावधान रहें कि आप इसका उपयोग कैसे करते हैं:जबकि now() STABLEहै (लेन-देन की अवधि के लिए नहीं बदलता), यह करता है लेन-देन के बीच परिवर्तन, इसलिए ध्यान रखें कि इसे तैयार किए गए बयानों (पैरामीटर मान को छोड़कर) या अनुक्रमणिका या ऐसी किसी भी चीज़ में उपयोग न करें जहाँ यह आपको काट सकता है।

3.) या आप प्रतीत होता है कि बेमानी स्थिरांक जोड़ सकते हैं WHERE आपकी वर्तमान क्वेरी के खंड जो आपके विभाजन की बाधा से मेल खाते हैं:

SELECT count(*)
FROM   events
WHERE  created_at > now() - '1 hour'::interval
AND    created_at >= '2015-04-01 00:00:00'::timestamp
AND    created_at <= '2015-04-30 23:59:59.999999'::timestamp;

बस स्वयं सुनिश्चित करें कि now() - '1 hour'::interval सही विभाजन में पड़ता है या आपको कोई परिणाम नहीं मिलता है, जाहिर है।

इसके अलावा:मैं इस अभिव्यक्ति का उपयोग CHECK . में करना चाहूंगा बाधाएं और क्वेरी। संभालना आसान और वही करता है:

       created_at >= '2015-04-01 0:0'::timestamp
AND    created_at <  '2015-05-01 0:0'::timestamp



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. विशेषता संख्या 10 कॉलम की संख्या से अधिक है 0

  2. पोस्टग्रेज:आप टाइमस्टैम्प को निकटतम मिनट में ऊपर या नीचे कैसे घुमाते हैं?

  3. SQL DDL कथन के लिए मौजूदा तालिका से स्तंभ नाम फ़िल्टर करें

  4. कॉलम के डेटा प्रकार को सीरियल में बदलें

  5. सबक्वेरी खराब प्रदर्शन के साथ PostgreSQL IN ऑपरेटर