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

प्रति दिन 1 से अधिक रिकॉर्ड कैसे चुनें?

<ब्लॉककोट>

मैं अधिकतम 3 रिकॉर्ड का चयन करना चाहता/चाहती हूं प्रति दिन एक विशिष्ट तिथि सीमा से।

SELECT date_time, other_column
FROM  (
   SELECT *, row_number() OVER (PARTITION BY date_time::date) AS rn
   FROM   tbl
   WHERE  date_time >= '2012-11-01 0:0'
   AND    date_time <  '2012-12-01 0:0'
   ) x
WHERE  rn < 4;

प्रमुख बिंदु

  • विंडो फ़ंक्शन का उपयोग करें row_number() . rank() या dense_rank() प्रश्न के अनुसार गलत होगा - टाइमस्टैम्प डुप्लिकेट के साथ 3 से अधिक रिकॉर्ड चुने जा सकते हैं।

  • चूंकि आप कौन से . को परिभाषित नहीं करते हैं पंक्तियाँ जो आप प्रति दिन चाहते हैं, सही उत्तर ORDER BY शामिल करना नहीं है विंडो फ़ंक्शन में क्लॉज। आपको एक मनमाना चयन देता है, जो प्रश्न से मेल खाता है।

  • मैंने आपका WHERE बदल दिया है खंड

    . से
    WHERE  date_time >= '20121101 00:00:00'  
    AND    date_time <= '20121130 23:59:59'
    

    करने के लिए

    WHERE  date_time >=  '2012-11-01 0:0'  
    AND    date_time <   '2012-12-01 0:0'
    

    '20121130 23:59:59.123' . जैसे कोने के मामलों के लिए आपका सिंटैक्स विफल हो जाएगा ।

    @ क्रेग ने क्या सुझाव दिया:

    date_time::date BETWEEN '2012-11-02' AND '2012-11-05'
    

    .. सही ढंग से काम करेगा, लेकिन प्रदर्शन के संबंध में एक विरोधी पैटर्न है। यदि आप एक्सप्रेशन में अपने डेटाबेस कॉलम में कास्ट या फ़ंक्शन लागू करते हैं, तो प्लेन इंडेक्स का उपयोग नहीं किया जा सकता है।

PostgreSQL 8.3 के लिए समाधान

सर्वश्रेष्ठ समाधान :अधिक हाल के संस्करण में अपग्रेड करें, अधिमानतः वर्तमान संस्करण 9.2 में।

अन्य समाधान :

केवल कुछ दिनों के लिए आप UNION ALL employ को नियोजित कर सकते हैं :

SELECT date_time, other_column
FROM   tbl t1
WHERE  date_time >= '2012-11-01 0:0'
AND    date_time <  '2012-11-02 0:0'
LIMIT  3
)
UNION ALL 
(
SELECT date_time, other_column
FROM   tbl t1
WHERE  date_time >= '2012-11-02 0:0'
AND    date_time <  '2012-11-03 0:0'
LIMIT  3
)
...

कोष्ठक यहाँ वैकल्पिक नहीं हैं।

और दिनों के लिए generate_series() . के साथ समाधान हैं - कुछ ऐसा मैंने यहां पोस्ट किया है (अधिक के लिए एक लिंक सहित)।

हो सकता है कि मैंने इसे plpgsql फ़ंक्शन . के साथ हल किया हो पुराने दिनों में वापस हमारे पास खिड़की के कार्य थे:

CREATE OR REPLACE FUNCTION x.f_foo (date, date, integer
                         , OUT date_time timestamp, OUT other_column text)
  RETURNS SETOF record AS
$BODY$
DECLARE
    _last_day date;          -- remember last day
    _ct       integer := 1;  -- count
BEGIN

FOR date_time, other_column IN
   SELECT t.date_time, t.other_column
   FROM   tbl t
   WHERE  t.date_time >= $1::timestamp
   AND    t.date_time <  ($2 + 1)::timestamp
   ORDER  BY t.date_time::date
LOOP
   IF date_time::date = _last_day THEN
      _ct := _ct + 1;
   ELSE
      _ct := 1;
   END IF;

   IF _ct <= $3 THEN
      RETURN NEXT;
   END IF;

   _last_day := date_time::date;
END LOOP;

END;
$BODY$ LANGUAGE plpgsql STABLE STRICT;

COMMENT ON FUNCTION f_foo(date3, date, integer) IS 'Return n rows per day
$1 .. date_from (incl.)
$2 .. date_to  (incl.)
$3 .. maximim rows per day';

कॉल करें:

SELECT * FROM f_foo('2012-11-01', '2012-11-05', 3);


  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 के लिए pt-pg-सारांश Percona टूलकिट का उपयोग करना

  2. Postgresql में, दो स्तंभों के संयोजन पर अद्वितीय बल दें

  3. PostgreSQL में डेटस्टाइल कैसे बदलें?

  4. JSON फ़ील्ड के अपडेट डीबी पर बने नहीं रहते हैं

  5. Postgresql इंटररे त्रुटि:अपरिभाषित प्रतीक:pfree