MySQL

2011-03-23 10 views
6

के साथ मध्यस्थ की गणना करना मुझे मूल्यों की सूची के औसत की गणना करने में समस्या हो रही है, औसत नहीं।MySQL

मैं इस लेख Simple way to calculate median with MySQL

यह निम्न क्वेरी जो मैं ठीक से समझ में नहीं आता के लिए एक संदर्भ है पाया।

से डेटा एक्स चयन x.val, डेटा Y से x.val ग्रुप योग होने (साइन इन करें (1-इन (y.val-x.val))) = (COUNT (*) +1)/2

यदि मेरे पास समय कॉलम है और मैं औसत मूल्य की गणना करना चाहता हूं, तो एक्स और वाई कॉलम क्या संदर्भित करते हैं?

+0

ध्यान दें कि आपके द्वारा उल्लिखित समाधान में डुप्लिकेट मान होने पर औसत नहीं मिलेगा। (यह तब विफल हो जाता है जब औसत में डुप्लिकेट होता है) –

+0

मैं ईमानदारी से समझ नहीं पा रहा हूं कि कैसे लाखों लोगों द्वारा MySQL का उपयोग किया जाता है और दशकों से आसपास रहा है लेकिन मध्यस्थ की गणना करने के लिए कोई फ़ंक्शन नहीं है। क्या कोई अन्य डेटा-केंद्रित सिस्टम है जिसने गणित को लागू नहीं किया है जिसे आमतौर पर 4-10 ग्रेड में 9-10 वर्ष के बच्चों को पढ़ाया जाता है? –

उत्तर

2

val आपका समय कॉलम है, x और y डेटा तालिका के दो संदर्भ हैं (आप data AS x, data AS y लिख सकते हैं)।

संपादित करें: अपनी रकम दो बार कंप्यूटिंग से बचने के लिए, आप मध्यवर्ती परिणामों को स्टोर कर सकते हैं।

CREATE TEMPORARY TABLE average_user_total_time 
     (SELECT SUM(time) AS time_taken 
      FROM scores 
      WHERE created_at >= '2010-10-10' 
        and created_at <= '2010-11-11' 
      GROUP BY user_id); 

तो फिर तुम इन मूल्यों को जो एक नामित तालिका में हैं पर मंझला गणना कर सकता है।

संपादित करें: अस्थायी तालिका won't work यहां। आप "मेमरी" टेबल प्रकार के साथ नियमित तालिका का उपयोग करने का प्रयास कर सकते हैं। या बस अपनी सबक्वायरी है जो आपकी क्वेरी में औसत से दो बार मानों की गणना करती है। इसके अलावा, मुझे एक और समाधान नहीं दिख रहा है। इसका मतलब यह नहीं है कि कोई बेहतर तरीका नहीं है, शायद कोई और विचार के साथ आएगा।

+0

उस @ केआरबी के लिए धन्यवाद! मान लीजिए कि आप निम्न में मेरी सहायता कर सकते हैं। चयन औसत (TIME_TAKEN) से (\t चयन योग ('time') TIME_TAKEN के रूप में स्कोर से कहां created_at> = '2010-10-10' और created_at <= '2010-11-11' user_id द्वारा समूह) के रूप में average_user_total_time ") उन अंकों के योग की औसत लेकिन यकीन है कि कैसे इस सवाल के मंझला फार्मूला लागू करने के लिए नहीं की गणना करने के। फिर से इस पद के लिए क्षमा करें, टाइम आउट हो गया। – Tim

+0

जब मैं उस की कोशिश, मैं "तालिका x को दोबारा नहीं खोल सकता"। यहां मेरा कुल वर्ग है। टेम्पलेट टेबल बनाएं औसत_user_total_time (चयन एसयूएम (समय) AS time_taken स्कोर से जहां बनाया गया_एट> = '2010-10-10' और बनाया_at <= '2010-11-11' उपयोगकर्ता_आईडी द्वारा समूह); एक्स चुनें।x_time_total_time के रूप में औसत_user_total_time x_ औसत_user_total_time के रूप में y ग्रुप द्वारा x.time_taken हैविंग एसयूएम (साइन (1-साइन (y.time_taken-x.time_taken)) = (COUNT (*) + 1)/2 – Tim

+0

ओह, मैं देखें: http://dev.mysql.com/doc/refman/5.0/en/temporary-table-problems.html – Krab

1

सबसे पहले यह समझने की कोशिश करें कि औसत क्या है: यह मूल्यों की क्रमबद्ध सूची में मध्य मूल्य है।

  1. तरह या तो आदेश
  2. मध्यम मान लेने में मानों (यदि नहीं मान विषम संख्या में, दो मध्य की औसत लेने:

    एक बार जब आप समझते हैं कि, दृष्टिकोण दो कदम है मान)

उदाहरण: यदि आप एक की जरूरत है

Median of 0 1 3 7 9 10: 5 (because (7+3)/2=5) 
Median of 0 1 3 7 9 10 11: 7 (because 7 is the middle value) 

तो, सॉर्ट करने के लिए दिनांक अंकीय मूल्य; आप अपना टाइम स्टैम्प प्राप्त कर सकते हैं (जैसे युग युग से निकलते हैं) और औसत की परिभाषा का उपयोग करते हैं।

+1

आपके पहले उदाहरण पर असहमत है: औसत हमेशा सेट का वास्तविक सदस्य होता है – zanlok

+4

@zanlok: किसी भी "अच्छी तरह से स्वीकृत" सॉफ़्टवेयर पैकेज मध्यस्थ की गणना करेगा जैसा कि मैंने प्रस्तुत किया है (औसत मूल्य यदि मूल्यों की संख्या भी है) Matlab औसत, R औसत। आप किस बारे में बात कर रहे हैं वह "medoid" है, जहां मान हमेशा डेटा सेट का सदस्य होता है। – Escualo

8

मैं एक तेज़ तरीका प्रस्तावित करता हूं।

पंक्ति संख्या प्राप्त करें:

SELECT CEIL(COUNT(*)/2) FROM data;

फिर एक क्रमबद्ध सबक्वेरी में मध्यम मान ले:

SELECT max(val) FROM (SELECT val FROM data ORDER BY val limit @middlevalue) x;

मैं यादृच्छिक संख्या की एक 5x10e6 डाटासेट के साथ इस परीक्षण किया है और कहीं भी होगी 10 सेकंड से कम उम्र में औसत पाएं।जहां n प्रतिशतक (मंझला के लिए .5, .75 75 वाँ प्रतिशतक के लिए, आदि) है

यह COUNT(*)*n साथ COUNT(*)/2 की जगह एक मनमाना प्रतिशतक मिल जाएगा।

+3

अच्छा समाधान लेकिन यदि आइटमों की एक विषम संख्या है तो आपको दो मध्य बिंदुओं का चयन प्राप्त करना चाहिए 'से चुनें औसत (वैल) (वैल सीमा @ मिडलवैल्यू, @ न्यूमल्व्यूज द्वारा डेटा ऑर्डर से वैल्यू वैल्यू एक्स;' जहां @ अंक '(@ मिडलवैल्यू मोड 2) + 1' –

+0

यह एकल क्वेरी/सबक्वायरीज़ में नहीं किया जा सकता है? –

1

group_concat का उपयोग कर mysql में मंझला ढूँढना

क्वेरी:

SELECT 
    IF(count%2=1, 
     SUBSTRING_INDEX(substring_index(data_str,",",pos),",",-1), 
     (SUBSTRING_INDEX(substring_index(data_str,",",pos),",",-1) 
     + SUBSTRING_INDEX(substring_index(data_str,",",pos+1),",",-1))/2) 
    as median 
FROM (SELECT group_concat(val order by val) data_str, 
     CEILING(count(*)/2) pos, 
     count(*) as count from data)temp; 

स्पष्टीकरण:

छंटाई अंदर group_concat समारोह से आदेश का उपयोग कर

स्थिति (पीओएस) किया जाता है और तत्वों की कुल संख्या (गिनती) पहचान है fied। स्थिति की पहचान करने के लिए CEILING हमें नीचे दिए गए चरणों में substring_index फ़ंक्शन का उपयोग करने में मदद करता है।

गिनती के आधार पर, मूल्यों की भी अजीब संख्या का निर्णय लिया जाता है।

  • विषम मान: substring_index का उपयोग करके सीधे pos से संबंधित तत्व का चयन करें।
  • यहां तक ​​कि मूल्य: pos और pos + 1 से संबंधित तत्व ढूंढें, फिर उन्हें जोड़ें और औसत प्राप्त करने के लिए 2 से विभाजित करें।

अंत में औसत की गणना की जाती है।

0

आप A नाम के एक स्तंभ के साथ एक मेज R है, और आप एक की मंझला चाहते हैं तो आपको इस प्रकार कर सकते हैं:

SELECT A FROM R R1 
WHERE (SELECT COUNT(A) FROM R R2 WHERE R2.A < R1.A) = (SELECT COUNT(A) FROM R R3 WHERE R3.A > R1.A) 

नोट: यह केवल देखते हैं अगर काम करेंगे ए में कोई डुप्लिकेट मान नहीं है, इसके अलावा, शून्य मानों की अनुमति नहीं है।

 संबंधित मुद्दे