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

Postgres में समय अंतराल के लिए औसत मान कैसे प्राप्त करें

DB डिज़ाइन

जबकि आप कर सकते हैं अलग से काम करें तारीख और समय कॉलम, वास्तव में एकल timestamp<पर कोई लाभ नहीं है /कोड> कॉलम। मैं अनुकूलित करूंगा:

ALTER TABLE tbl ADD column ts timestamp;
UPDATE tbl SET ts = date + time;  -- assuming actual date and time types
ALTER TABLE tbl DROP column date, DROP column time;

यदि दिनांक और समय वास्तविक नहीं हैं तारीख और समय डेटा प्रकार, उपयोग करें to_timestamp() . संबंधित:

क्वेरी

फिर क्वेरी थोड़ी आसान हो जाती है:

SELECT *
FROM  (
   SELECT sn, generate_series(min(ts), max(ts), interval '5 min') AS ts
   FROM   tbl
   WHERE  sn = '4as11111111'
   AND    ts >= '2018-01-01'
   AND    ts <  '2018-01-02'
   GROUP  BY 1
   ) grid
CROSS  JOIN LATERAL (
   SELECT round(avg(vin1), 2) AS vin1_av
        , round(avg(vin2), 2) AS vin2_av
        , round(avg(vin3), 2) AS vin3_av
   FROM   tbl
   WHERE  sn =  grid.sn
   AND    ts >= grid.ts
   AND    ts <  grid.ts + interval '5 min'
   ) avg;

db<>fiddle यहां

पहली सबक्वेरी ग्रिड . में प्रारंभ समय का ग्रिड जेनरेट करें , प्रथम से अंतिम योग्यता . तक चल रहा है दी गई समय सीमा में पंक्ति।

प्रत्येक पार्टीशन में आने वाली पंक्तियों में LATERAL . के साथ शामिल हों सबक्वेरी औसत . में शामिल हों और तुरंत औसत एकत्र करें . समुच्चय के कारण, यह हमेशा कोई प्रविष्टि नहीं मिलने पर भी एक पंक्ति लौटाता है। औसत डिफ़ॉल्ट NULL . है इस मामले में।

परिणाम में दी गई समय सीमा में पहली और अंतिम क्वालीफाइंग पंक्ति के बीच सभी समय स्लॉट शामिल हैं। विभिन्न अन्य परिणाम रचनाएँ भी समझ में आएंगी। जैसे सभी को शामिल करना दी गई समय सीमा में समय स्लॉट या वास्तविक मूल्यों के साथ केवल समय स्लॉट। हर संभव, मुझे एक व्याख्या चुननी पड़ी।

सूचकांक

कम से कम यह बहु-स्तंभ अनुक्रमणिका रखें:

CRATE INDEX foo_idx ON tbl (sn, ts);

या (sn, ts, vin1, vin2, vin3) . पर केवल अनुक्रमणिका स्कैन की अनुमति देने के लिए - यदि कुछ पूर्व शर्त पूरी होती हैं और विशेष रूप से यदि तालिका पंक्तियाँ डेमो की तुलना में बहुत व्यापक हैं।

निकट से संबंधित:

आपकी मूल तालिका के आधार पर

जैसा अनुरोध किया गया है और टिप्पणी में स्पष्ट किया गया है , और बाद में कॉलम mac . को शामिल करने के लिए प्रश्न में फिर से अपडेट किया गया और स्थान . मुझे लगता है कि आप प्रति (mac, loc) . के लिए अलग औसत चाहते हैं ।

तारीख और समय अभी भी अलग कॉलम हैं, vin* कॉलम टाइप हैं float , और पंक्तियों के बिना समय स्लॉट बहिष्कृत करें:

अपडेट की गई क्वेरी सेट-रिटर्निंग फ़ंक्शन को भी स्थानांतरित करती है generate_series() से . तक सूची, जो पोस्टग्रेज 10 से पहले साफ-सुथरी है:

SELECT t.mac, sn.sn, t.loc, ts.ts::time AS time, ts.ts::date AS date
     , t.vin1_av, t.vin2_av, t.vin3_av
FROM  (SELECT text '4as11111111') sn(sn)  -- provide sn here once
CROSS  JOIN LATERAL (
   SELECT min(date+time) AS min_ts, max(date+time) AS max_ts
   FROM   tbl
   WHERE  sn = sn.sn
   AND    date+time >= '2018-01-01 0:0'   -- provide time frame here
   AND    date+time <  '2018-01-02 0:0'
   ) grid
CROSS  JOIN LATERAL generate_series(min_ts, max_ts, interval '5 min') ts(ts)
CROSS  JOIN LATERAL (
   SELECT mac, loc
        , round(avg(vin1)::numeric, 2) AS vin1_av  -- cast to numeric for round()
        , round(avg(vin2)::numeric, 2) AS vin2_av  -- but rounding is optional
        , round(avg(vin3)::numeric, 2) AS vin3_av
   FROM   tbl
   WHERE  sn = sn.sn
   AND    date+time >= ts.ts
   AND    date+time <  ts.ts + interval '5 min'
   GROUP  BY mac, loc
   HAVING count(*) > 0  -- exclude empty slots
   ) t;

इसका समर्थन करने के लिए एक बहु-स्तंभ अभिव्यक्ति अनुक्रमणिका बनाएं:

CRATE INDEX bar_idx ON tbl (sn, (date+time));

db<>fiddle यहां

लेकिन मैं इसके बजाय टाइमस्टैम्प का अधिक उपयोग करूंगा साथ में।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. बैकअप PostgreSQL pg_dump और pg_dumpall का उपयोग कर

  2. ON CONFLICT से मेल खाने वाली कोई अनूठी या बहिष्करण बाधा नहीं है

  3. टाइपओआरएम ट्रांसफॉर्मर के साथ ऑपरेटर खोजें

  4. जब लेन-देन पूलिंग सक्षम होती है और एक ही स्टेटमेंट जारी किया जाता है, तो pgbouncer कैसे व्यवहार करता है?

  5. सर्वर से कनेक्ट करने में असमर्थ:लिनक्स के लिए विंडोज़ सबसिस्टम में ubuntu पर postgresql