दिलचस्प पोस्ट
क्या PHP फ़ंक्शन केस संवेदनशील है? एंड्रॉइड में ऐरे एडाप्टर का उपयोग करके कस्टम फ़िल्टरिंग जावास्क्रिप्ट .प्रोटोटाइप कैसे काम करता है? सी प्रोग्रामिंग: मॉलोक () दूसरे फ़ंक्शन के अंदर ViewModel में कमांड के लिए WPF बाध्यकारी यूआई इवेंट्स एक्सेस-कंट्रोल-अनुमति-मूल बाईपास कैसे करें? Launch4j के साथ एक JRE बंडल करने के लिए कैसे? जावा में सिंगलटन पैटर्न को लागू करने का एक प्रभावी तरीका क्या है? लंबे पूर्णांक के लिए अधिकतम मान "मानक" समयक्षेत्र संक्षेप क्या हैं? एकाधिक कॉलम पर समूह का उपयोग करना सी # में enum को कास्ट करें एक शब्दकोश से वस्तुओं को हटाने के लिए कैसे करें? JavaFX आवधिक पृष्ठभूमि कार्य कैसे django टेम्पलेट में शब्दकोश तत्व का उपयोग करने के लिए?

MySQL में वर्गीकृत रैंकिंग कैसे करें

इसलिए मेरे पास टेबल है:

ID_STUDENT | ID_CLASS | GRADE ----------------------------- 1 | 1 | 90 1 | 2 | 80 2 | 1 | 99 3 | 1 | 80 4 | 1 | 70 5 | 2 | 78 6 | 2 | 90 6 | 3 | 50 7 | 3 | 90 

मुझे तब समूह की ज़रूरत है, उन्हें सॉर्ट और ऑर्डर देने के लिए:

 ID_STUDENT | ID_CLASS | GRADE | RANK ------------------------------------ 2 | 1 | 99 | 1 1 | 1 | 90 | 2 3 | 1 | 80 | 3 4 | 1 | 70 | 4 6 | 2 | 90 | 1 1 | 2 | 80 | 2 5 | 2 | 78 | 3 7 | 3 | 90 | 1 6 | 3 | 50 | 2 

अब मुझे पता है कि आप यहाँ की तरह रैंक करने के लिए एक अस्थायी चर का उपयोग कर सकते हैं, लेकिन मैं इसे समूहित सेट के लिए कैसे कर सकता हूं? किसी भी अंतर्दृष्टि के लिए धन्यवाद!

वेब के समाधान से एकत्रित समाधान "MySQL में वर्गीकृत रैंकिंग कैसे करें"

 SELECT id_student, id_class, grade, @student:=CASE WHEN @class <> id_class THEN 0 ELSE @student+1 END AS rn, @class:=id_class AS clset FROM (SELECT @student:= -1) s, (SELECT @class:= -1) c, (SELECT * FROM mytable ORDER BY id_class, id_student ) t 

यह एक बहुत ही सरल तरीके से काम करता है:

  1. प्रारंभिक क्वेरी का आदेश id_class पहले, id_student second द्वारा दिया गया है।
  2. @student और @class को -1 आरंभ किया जाता है
  3. @class का परीक्षण करने के लिए प्रयोग किया जाता है कि अगले सेट में प्रवेश किया है या नहीं। यदि id_class का पिछला मूल्य (जो @class में संग्रहीत है) मौजूदा मान (जो @class में संग्रहीत है) के बराबर नहीं है, तो @student को @student जाता है। अन्यथा वृद्धि हुई है।
  4. @class को @class के नए मूल्य के साथ सौंपा गया है, और यह अगले पंक्ति में चरण 3 पर परीक्षण में उपयोग किया जाएगा।

क्वॉसनोई के समाधान के साथ एक समस्या है (सर्वोत्तम उत्तर के रूप में चिह्नित)

मेरे पास एक ही समस्या है (यानी MySQL में एसक्यूएल विंडो फ़ंक्शन का अनुकरण करना) और मैं क्वॉस्नोई के समाधान को कार्यान्वित करने के लिए प्रयोग किया, जो कि पिछले पंक्ति मान को संग्रहीत करने के लिए उपयोगकर्ता परिभाषित चर का उपयोग कर रहा था …

लेकिन, शायद एक MySQL अपग्रेड के बाद या जो भी हो, मेरी क्वेरी अब और काम नहीं करती थी। ऐसा इसलिए है क्योंकि SELECT में फ़ील्ड के मूल्यांकन के क्रम की गारंटी नहीं है। @ वर्ग असाइनमेंट @ स्टूडेंट असाइनमेंट से पहले मूल्यांकन किया जा सकता है, भले ही उसे SELECT में रखा गया हो।

इस प्रकार MySQL प्रलेखन में उल्लेख किया गया है:

एक सामान्य नियम के रूप में, आपको उपयोगकर्ता वैरिएबल के लिए एक मान कभी भी निर्दिष्ट नहीं करना चाहिए और उसी कथन के भीतर मान पढ़ना चाहिए। आपको उम्मीद है कि परिणाम प्राप्त हो सकते हैं, लेकिन इसकी गारंटी नहीं है उपयोगकर्ता चर को शामिल करने वाले भावों के मूल्यांकन के क्रम अनिश्चित हैं और किसी दिए गए बयान में निहित तत्वों के आधार पर बदल सकते हैं; इसके अतिरिक्त, यह ऑर्डर MySQL सर्वर के रिलीज के बीच समान होने की गारंटी नहीं है

स्रोत: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html

आखिरकार मैंने एक युगल का इस्तेमाल किया है जो इसे पढ़ने के बाद @ वर्ग आवंटित करना सुनिश्चित करता है:

 SELECT id_student, id_class, grade, @student:=CASE WHEN @class <> id_class THEN concat(left(@class:=id_class, 0), 0) ELSE @student+1 END AS rn FROM (SELECT @student:= -1) s, (SELECT @class:= -1) c, (SELECT * FROM mytable ORDER BY id_class, grade desc ) t 

बाएं () फ़ंक्शन का उपयोग करने के लिए बस @class variable सेट करने के लिए उपयोग किया जाता है उसके बाद, बाएं () (नल के बराबर) के नतीजे को सम्मिलित करना अपेक्षित परिणाम पारदर्शी है।

बहुत सुंदर नहीं है, लेकिन यह काम करता है!

ऊपर से संशोधित, यह काम करता है, लेकिन इसकी तुलना में मुझे लगता है कि यह बहुत जटिल है:

 SELECT ID_STUDENT, ID_CLASS, GRADE, RANK FROM (SELECT ID_STUDENT, ID_CLASS, GRADE, @student:=CASE WHEN @class <> id_class THEN 1 ELSE @student+1 END AS RANK, @class:=id_class AS CLASS FROM (SELECT @student:= 0) AS s, (SELECT @class:= 0) AS c, (SELECT * FROM Students ORDER BY ID_CLASS, GRADE DESC ) AS temp ) AS temp2 
 SELECT g1.student_id , g1.class_id , g1.grade , COUNT(*) AS rank FROM grades AS g1 JOIN grades AS g2 ON (g2.grade, g2.student_id) >= (g1.grade, g1.student_id) AND g1.class_id = g2.class_id GROUP BY g1.student_id , g1.class_id , g1.grade ORDER BY g1.class_id , rank ; 

परिणाम:

 +------------+----------+-------+------+ | student_id | class_id | grade | rank | +------------+----------+-------+------+ | 2 | 1 | 99 | 1 | | 1 | 1 | 90 | 2 | | 3 | 1 | 80 | 3 | | 4 | 1 | 70 | 4 | | 6 | 2 | 90 | 1 | | 1 | 2 | 80 | 2 | | 5 | 2 | 78 | 3 | | 7 | 3 | 90 | 1 | | 6 | 3 | 50 | 2 | +------------+----------+-------+------+ 

मैंने कुछ शोध किया, इस समाधान के साथ आने के लिए इस आलेख को मिला:

 SELECT S2.*, FIND_IN_SET( S2.GRADE , ( SELECT GROUP_CONCAT(GRADE ORDER BY GRADE DESC) FROM Students S1 WHERE S1.ID_CLASS = S2.ID_CLASS ) ) AS RANK FROM Students S2 ORDER BY ID_CLASS, GRADE DESC; 

जिस पर कोई विचार बेहतर है?