2012-12-24 13 views
12

क्या I'am कर:अजीब MySQL औसत() विसंगति शून्य मान

create table sample (id INT(10) PRIMARY KEY AUTO_INCREMENT,name varchar(255),marks INT(10)); 

insert into sample (name,marks) VALUES('sam',10); 
insert into sample (name,marks) VALUES('sam',20); 
insert into sample (name,marks) VALUES('sam',NULL); 
insert into sample (name,marks) VALUES('sam',NULL); 
insert into sample (name,marks) VALUES('sam',30); 

select AVG(marks) from sample GROUP BY(name); 

आउटपुट मैं उम्मीद:

औसत = (10 + 20 + 30)/5 = 12

MySQL के

उत्पादन:

औसत = (10 + 20 + 30)/3 = 20

मैं आदर्श रूप में क्या चाहता था कि MYSQL 5 पंक्तियों का योग हो और 5 से विभाजित करना चाहिए, लेकिन यह केवल 3 से विभाजित करता है (गैर-नल पंक्तियां)

ऐसा क्यों होता है और मैं सही AVG यानी 60/5 प्राप्त करने के लिए क्या कर सकता हूं? पीएस: मैं अंकों के क्षेत्र को शून्य नहीं बना सकता, मेरे डीबी डिजाइन में अंक फ़ील्ड को पूर्ण होने की अनुमति है।

, आप

+1

मेरे जवाब देने के लिए और भी अधिक विवरण और संदर्भ जोड़ा – Kaii

+0

धन्यवाद @Kaii कि :) –

उत्तर

33

यह सही व्यवहार है धन्यवाद क्योंकि NULL संख्या 0 के रूप में ही नहीं है।

संकल्पनात्मक रूप से, NULL का अर्थ है "एक अज्ञात अज्ञात मान" और इसका अन्य मूल्यों से कुछ अलग तरीके से व्यवहार किया जाता है। यही कारण है कि aggregate functionsAVG()NULL एस को अनदेखा करें।

AVG() सभी निर्दिष्ट मानों से अधिक औसत की गणना करता है। (= कि नहीं NULL होते हैं)

MySQL docs से:

जब तक अन्यथा कहा गया है, समूह के कार्यों शून्य मान ध्यान न दें।

इसके अलावा, NULL एस Section "3.3.4.6 Working with NULL Values" में MySQL मैनुअल की अवधारणा के बारे में पढ़ें।

आप क्या चाहते हैं, तो आप

SELECT AVG(IFNULL(marks, 0)) FROM sample GROUP BY(name); 

IFNULL() रिटर्न की गणना के लिए दूसरा तर्क है, तो मूल्य NULL है या अन्यथा मूल्य के माध्यम से गुजरता कर सकता प्राप्त करने के लिए।


NULL की अवधारणा के बारे में अधिक गलतफहमीईन रहे हैं। ये भी मैनुअल के Section "5.5.3 Problems with NULL" से वर्णन किया गया:

  • एसक्यूएल में, `NULL` मूल्य कभी नहीं सच किसी अन्य मूल्य की तुलना में, है भी` NULL`। एक अभिव्यक्ति जिसमें 'NULL` होता है हमेशा एक' NULL` मान उत्पन्न करता है जब तक अन्यथा अभिव्यक्ति में शामिल ऑपरेटरों और कार्यों के लिए दस्तावेज़ में इंगित नहीं किया जाता है।

    यानी।: `NULL == 0` परिणाम 'सत्य' के बजाय NULL में परिणाम। इसके अलावा 'NULL == NULL` नतीजे के बजाय, सत्य के बजाय परिणाम।
  • 'न्यूल' वाले कॉलम मानों की खोज के लिए, आप 'expr = NULL` परीक्षण का उपयोग नहीं कर सकते हैं। `NULL` मानों को देखने के लिए, आपको 'IS NULL` परीक्षण का उपयोग करना होगा।
  • `DISTINCT`, 'GROUP BY`, या` ORDER BY` का उपयोग करते समय, सभी `NULL` मानों को बराबर माना जाता है।
  • `ORDER BY` का उपयोग करते समय,` NULL` मान पहले प्रस्तुत किए जाते हैं, या अंतिम यदि आप अवरोही क्रम में क्रमबद्ध करने के लिए 'DESC` निर्दिष्ट करते हैं।
  • कुछ डेटा प्रकारों के लिए, MySQL विशेष रूप से नल मानों को संभालता है। यदि आप `NULL` को 'TIMESTAMP` कॉलम में डालते हैं, तो वर्तमान दिनांक और समय डाला जाता है।
  • यदि आप 'पूर्ण' को एक पूर्णांक या फ़्लोटिंग-पॉइंट कॉलम में डालते हैं जिसमें 'ऑटोऑर्डरक्रिएशन' विशेषता है, तो अनुक्रम में अगला नंबर डाला गया है।
  • एक कॉलम जिसमें 'अद्वितीय' कुंजी परिभाषित है, में अभी भी कई 'शून्य' मान हो सकते हैं।
+0

धन्यवाद @kaii मदद की, कि समाधान में मदद की, मैं छाप mySQL तरह = योग/(स्तंभों की ओपन स्कूल औसत प्रदर्शन के तहत किया गया परिणामस्वरूप) –

2

प्रयास करें:

select avg(case marks when null then 0 else marks end) from sample group by name; 

या कोशिश करते हैं और तालिका में nulls से बचने के;)

+0

मदद @fge के लिए धन्यवाद –

1

आप इस के बजाय कर सकते हैं:

SELECT SUM(marks)/COUNT(name) 
FROM sample 
GROUP BY name; 
1

सामान्य व्यवहार है यही कारण है, शून्य के बाद से शून्य नहीं है आप 5 + एनयूएलएल का औसत कैसे बनाते हैं? तो MySQL केवल पंक्तियों को ले रहा है जिसे औसत किया जा सकता है।

अन्य उपयोगकर्ताओं ने आपको पहले से ही दिए गए सही उत्तरों से एपर्ट करें, आप COALESCE फ़ंक्शन का भी उपयोग कर सकते हैं, जो सूची में निर्दिष्ट पहले गैर-नल मान को वापस लौटाता है, ताकि आप अपनी पसंद के साथ नल को प्रतिस्थापित कर सकें :

SELECT AVG(COALESCE(marks,0)) FROM sample GROUP BY(name); 
संबंधित मुद्दे