Q1:डेटाबेस इन दो तिथियों के औसत के लिए एक मान्य मान क्यों नहीं लौटाता?
ए: लौटाया गया मान अपेक्षित है, यह अच्छी तरह से परिभाषित MySQL व्यवहार है।
MySQL संदर्भ मैनुअल:https://dev .mysql.com/doc/refman/5.5/hi/date-and-time-types.html
MySQL में, AVG
एग्रीगेट फ़ंक्शन संख्यात्मक . पर काम करता है मान।
MySQL में, एक DATE
या DATETIME
अभिव्यक्ति का मूल्यांकन संख्यात्मक . में किया जा सकता है प्रसंग।
एक साधारण प्रदर्शन के रूप में, एक संख्यात्मक प्रदर्शन करना DATETIME
पर अतिरिक्त कार्रवाई डेटाटाइम मान को एक संख्या में निहित रूप से परिवर्तित करता है। यह प्रश्न:
SELECT NOW(), NOW()+0
जैसे परिणाम देता है:
NOW() NOW()+0
------------------- -----------------------
2015-06-23 17:57:48 20150623175748.000000
ध्यान दें कि व्यंजक NOW()+0
. के लिए लौटाया गया मान है नहीं एक DATETIME
, यह एक संख्या . है ।
जब आप SUM()
specify निर्दिष्ट करते हैं या AVG()
DATETIME
पर कार्य करें अभिव्यक्ति, जो DATETIME
. को रूपांतरित करने के बराबर है एक संख्या में, और फिर संक्षेप या संख्या का औसत।
यानी, इस एक्सप्रेशन से वापसी AVG(mydatetimecol)
इस अभिव्यक्ति से वापसी के बराबर है:AVG(mydatetimecol+0)
क्या "औसत" किया जा रहा है एक संख्यात्मक मान है। और आपने देखा है, लौटाया गया मान मान्य डेटाटाइम नहीं है; और यहां तक कि ऐसे मामलों में जहां यह एक वैध डेटाटाइम की तरह दिखता है, यह संभवत:एक ऐसा मूल्य नहीं है जिसे आप एक सच्चे "औसत" पर विचार करेंगे।
Q2:यदि वर्णित तरीका विफल हो जाता है तो मैं इस क्षेत्र का वास्तविक औसत कैसे प्राप्त करूं?
A2: ऐसा करने का एक तरीका यह है कि डेटाटाइम को एक संख्यात्मक मान में परिवर्तित किया जाए जिसे "सटीक रूप से" औसत किया जा सकता है, और फिर उसे वापस डेटाटाइम में परिवर्तित किया जा सकता है।
उदाहरण के लिए, आप डेटाटाइम को एक संख्यात्मक मान में बदल सकते हैं जो सेकंड की संख्या . का प्रतिनिधित्व करता है कुछ निश्चित समय से, उदा.
TIMESTAMPDIFF(SECOND,'2015-01-01',t.my_date)
फिर आप औसत सेकंड की संख्या . प्राप्त करने के लिए उन मानों को "औसत" कर सकते हैं एक निश्चित समय से। (नोट:बहुत बड़ी संख्या में पंक्तियों को जोड़ने से सावधान रहें, बहुत बड़े मानों के साथ, और सीमा से अधिक (अधिकतम संख्यात्मक मान), संख्यात्मक अतिप्रवाह मुद्दे।)
AVG(TIMESTAMPDIFF(SECOND,'2015-01-01',t.my_date))
इसे वापस डेटाटाइम में बदलने के लिए, उस मान को सेकंड की संख्या . के रूप में जोड़ें एक निश्चित समय पर वापस:
'2015-01-01' + INTERVAL AVG(TIMESTAMPDIFF(SECOND,'2015-01-01',t.my_date)) SECOND
(ध्यान दें कि DATEIME
मानों का मूल्यांकन MySQL सत्र के समयक्षेत्र में किया जाता है; इसलिए ऐसे किनारे के मामले हैं जहां time_zone
. की सेटिंग MySQL सत्र में चर का लौटाए गए मान पर कुछ प्रभाव पड़ेगा।)
MySQL एक UNIX_TIMESTAMP()
भी प्रदान करता है फ़ंक्शन जो एक यूनिक्स-शैली पूर्णांक मान देता है, युग की शुरुआत से सेकंड की संख्या (मध्यरात्रि 1 जनवरी, 1970 यूटीसी)। आप उसी ऑपरेशन को अधिक संक्षिप्त रूप से पूरा करने के लिए इसका उपयोग कर सकते हैं:
FROM_UNIXTIME(AVG(UNIX_TIMESTAMP(t.my_date)))
ध्यान दें कि यह अंतिम अभिव्यक्ति वास्तव में वही काम कर रही है ... '1970-01-01 00:00:00' यूटीसी के बाद से डेटाटाइम मान को कई सेकंड में परिवर्तित करना, उसमें से एक संख्यात्मक औसत लेना, और फिर उस औसत को जोड़ना '1970-01-01' यूटीसी के लिए सेकंड की संख्या, और अंत में इसे वापस DATETIME
में परिवर्तित करना मान, वर्तमान सत्र time_zone
. में दर्शाया गया है ।
Q3:क्या Django DateTimeField औसत को संभालने के लिए सेटअप नहीं है?
ए: जाहिर है, Django के लेखक SQL अभिव्यक्ति के लिए डेटाबेस से लौटाए गए मान से संतुष्ट हैं AVG(datetime)
।