जस्टिन और Sebas के उत्तरों की एक वाम के साथ बढ़ाया जा सकता है शामिल हों के लिए बराबर का उपयोग कर, "अंतराल" को खत्म करने की जो अक्सर वांछनीय है ओरेकल के लिए अनुकूल होना चाहिए।
अगर ऐसा आवश्यक नहीं है, एक विकल्प के रूप में, हम पुराने स्कूल ओरेकल, DATE अंकगणित जा सकते हैं ...
SELECT TRUNC(t.time)+FLOOR(TO_CHAR(t.time,'sssss')/300)*300/86400 AS time
, AVG(t.value) AS avg_value
FROM foo t
WHERE t.time IS NOT NULL
GROUP BY TRUNC(t.time)+FLOOR(TO_CHAR(t.time,'sssss')/300)*300/86400
ORDER BY TRUNC(t.time)+FLOOR(TO_CHAR(t.time,'sssss')/300)*300/86400
के एक सा है कि खोल दें। हम दिनांक भाग प्राप्त करने के लिए TRUNC का उपयोग करके दिनांक और समय घटकों को अलग कर सकते हैं, और मध्यरात्रि से सेकेंड की संख्या वापस करने के लिए TO_CHAR का उपयोग कर सकते हैं। हम जानते हैं कि 5 मिनट 300 सेकंड हैं, और हम जानते हैं कि दिन में 86400 सेकेंड हैं। इसलिए हम 300 से सेकंड की संख्या को विभाजित कर सकते हैं, और उस (केवल पूर्णांक भाग) का फ़्लोर ले सकते हैं, जो हमें निकटतम 5 मिनट की सीमा तक ले जाता है। हम सेकंड को फिर से प्राप्त करने के लिए उस बैक (300 से) गुणा करते हैं, और फिर उस दिन को विभाजित करते हैं (86400), और हम इसे वापस (संक्षिप्त) दिनांक भाग में जोड़ सकते हैं।
दर्दनाक, हाँ। लेकिन तेजस्वी तेजी से।
नोट: यह गोलाकार समय मान DATE
के रूप में देता है, इसे आवश्यक होने पर टाइमस्टैम्प पर वापस लाया जा सकता है, लेकिन 5 मिनट की सीमाओं के लिए, DATE
में पर्याप्त रिज़ॉल्यूशन है।
CREATE INDEX foo_FBX1
ON foo (TRUNC(t.time)+FLOOR(TO_CHAR(t.time,'sssss')/300)*300/86400,value);
परिशिष्ट:
इस दृष्टिकोण का एक लाभ के रूप में, एक बड़ी मेज के लिए, हम क्वेरी के प्रदर्शन इस प्रश्न के लिए एक कवर सूचकांक जोड़कर बढ़ा सकते हैं MiMo ने SQL सर्वर के लिए एक उत्तर प्रदान किया, यह सुझाव दिया कि यह ओरेकल के लिए अनुकूलनीय होगा। ओरेकल में उस दृष्टिकोण का एक अनुकूलन यहां दिया गया है। ध्यान दें कि ओरेकल DATEDIFF और DATEADD फ़ंक्शंस के लिए समकक्ष प्रदान नहीं करता है। ओरेकल इसके बजाय सरल अंकगणित का उपयोग करता है।
SELECT TO_DATE('00010101','YYYYMMDD')+FLOOR((t.time-TO_DATE('00010101','YYYYMMDD'))*288)/288
AS time
, AVG(t.value) AS avg_value
FROM foo t
WHERE t.time IS NOT NULL
GROUP BY TO_DATE('00010101','YYYYMMDD')+FLOOR((t.time-TO_DATE('00010101','YYYYMMDD'))*288)/288
ORDER BY TO_DATE('00010101','YYYYMMDD')+FLOOR((t.time-TO_DATE('00010101','YYYYMMDD'))*288)/288
1 जनवरी विकल्प है, एक आधार तिथि के रूप में 0001 ई मनमाना है, लेकिन मैं नकारात्मक मूल्यों के साथ गड़बड़ नहीं करना चाहता था, और पता लगाना है, तो मंजिल सही हो सकता है, या कि क्या हम उनका उपयोग करना होगा नकारात्मक संख्या के साथ सीईआईएल। (जादू संख्या 288 540 से विभाजित दिन में 1440 मिनट का परिणाम है)। इस मामले में, हम आंशिक दिन ले रहे हैं, 1440 तक गुणा कर रहे हैं और 5 से विभाजित कर रहे हैं, और इसके पूर्णांक हिस्से को ले रहे हैं, और फिर इसे वापस आंशिक दिनों में डाल रहे हैं।
यह पीएल/एसक्यूएल पैकेज से "बेस डेट" खींचने के लिए मोहक है, या इसे सबक्वायरी से प्राप्त करें, लेकिन इनमें से कोई भी इस अभिव्यक्ति को निर्धारक होने से रोक सकता है। और हम वास्तव में फ़ंक्शन आधारित इंडेक्स बनाने का विकल्प खोलना चाहते हैं।
मेरी प्राथमिकता गणना में "आधार तिथि" को शामिल करने की आवश्यकता से बचने के लिए है।
ओरेकल संस्करण 10 जी +? – Sebas
हां, क्षमा करें - 10 जी – Nick