मैं अधिकतम 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);