2014-06-09 11 views
5

मैं एसक्यूएल के लिए नया हूं और मैंने कभी भी mysql में चर या शर्तों का उपयोग नहीं किया है, लेकिन अन्य प्रोग्रामिंग भाषाओं से यह पता है। कुछ दिनों से मैं उपयोगकर्ता स्कोर रैंक करने का एक तरीका खोजने का प्रयास करता हूं। मैंने बहुत से लेख पढ़े, और स्टैक ओवरफ्लो पर पूछे जाने वाले प्रश्न भी और अंततः मुझे एक समाधान मिला जो लगभग मुझे पसंद है।संबंधों के साथ MySQL रैंक

SELECT 
    score_users.uid, 
    score_users.score, 
    @prev := @curr, 
    @curr := score, 
    @rank := IF(@prev = @curr, @rank, @rank +1) AS rank 
FROM 
    score_users, 
    (SELECT @curr := null, @prev := null, @rank := 0) tmp_tbl 
WHERE 
    score_users.matchday = 1 
ORDER BY 
    score_users.score DESC 

लेकिन मेरी समस्याएं टाई स्कोर हैं। मैं इस तरह लगातार रैंक प्राप्त करने के लिए, नहीं करना चाहती:

+------------+------+--------+ 
| uid | name | rank | score | 
+------------+------+--------+ 
| 4 | Jon | 1 | 20 | 
| 1 | Jane | 2 | 19 | 
| 2 | Fred | 2 | 19 | 
| 9 | July | 3 | 18 | 
| 7 | Mary | 4 | 17 | 
| 3 | Toni | 5 | 12 | 
| 5 | Steve | 5 | 12 | 
| 6 | Peter | 6 | 11 | 
| 8 | Nina | 7 | 10 | 
+------------+------+--------+ 

मैं इस तरह एक परिणाम प्राप्त करना चाहते हैं:,

+------------+------+--------+ 
| uid | name | rank | score | 
+------------+------+--------+ 
| 4 | Jon | 1 | 20 | 
| 1 | Jane | 2 | 19 | 
| 2 | Fred | 2 | 19 | 
| 9 | July | 4 | 18 | 
| 7 | Mary | 5 | 17 | 
| 3 | Toni | 6 | 12 | 
| 5 | Steve | 6 | 12 | 
| 6 | Peter | 8 | 11 | 
| 8 | Nina | 9 | 10 | 
+------------+------+--------+ 

मुझे लगता है मैं एक नया अस्थायी तालिका बनाने के लिए है और कुछ अगर हालात, लेकिन मुझे कोई समाधान नहीं मिला और वह बेताब हो गया! इसके अलावा, मुझे प्रदर्शन पर नजर रखना है, शायद स्कोर पर रैंक पाने के बेहतर तरीके हैं जैसा मैंने किया था? मैं संकेत या कुछ कोड स्निपेट के लिए बहुत आभारी होंगे।

+0

मैं एसक्यूएल के बाहर रैंक उत्पन्न होता है क्योंकि यह आसान है जो कुछ भी कार्यक्रम आप उपयोग कर रहे (स्कोर से रैंकिंग पर्याप्त है) के साथ क्या करना के बाद। आप जो कर रहे हैं वह करना MySQL में जटिल है! – serakfalcon

उत्तर

3

आप 1 के @rank बढ़ाने की तो बजाय एक ही रैंक गिनती करने के लिए एक और चर का उपयोग कर सकते हैं, तो आप काउंटर मूल्य द्वारा @rank को बढ़ा देते, इस तरह:

SELECT 
    score_users.uid, 
    score_users.score, 
    @prev := @curr, 
    @curr := score, 
    @rank := IF(@prev = @curr, @rank, @rank + @i) AS rank, 
    IF(@prev <> score, @i:=1, @i:[email protected]+1) AS counter 
FROM 
    score_users, 
    (SELECT @curr := null, @prev := null, @rank := 0, @i := 0) tmp_tbl 
WHERE 
    score_users.matchday = 1 
ORDER BY 
    score_users.score DESC 
+1

धन्यवाद अज़ीज़, यह बहुत अच्छी तरह से काम करता है। मैंने बस उप-चयन में @ रैंक को 1 सेट किया है, अन्यथा रैंकिंग 0 से शुरू हुई है! चियर्स – FredFus

0

एक और रैंक क्षेत्र जो हमेशा वृद्धि की जाती है जोड़ें। यदि मान मिलान करता है तो आप अपने मौजूदा रैंक (वृद्धि नहीं) का उपयोग करते हैं, यदि आप अपने हमेशा बढ़ी हुई रैंक का उपयोग नहीं करते हैं।

SELECT 
    score_users.uid, 
    score_users.score, 
    @prev := @curr, 
    @curr := score, 
    @rank1 := @rank1 + 1, 
    @rank := IF(@prev = @curr, @rank, @rank1) AS rank 
FROM 
    score_users, 
    (SELECT @curr := null, @prev := null, @rank := 0, @rank1 := 0) tmp_tbl 
WHERE 
    score_users.matchday = 1 
ORDER BY 
    score_users.score DESC 
0

संबंधों पर, आप अगले पंक्ति के रूप में अगले बेजोड़ स्कोर मूल्य पंक्ति पर वर्तमान पंक्ति संख्या को छोड़ना और उपयोग करना चाह सकते हैं। , मदद करनी चाहिए आप

SELECT 
    score_users.uid 
    , @curr_score := score_users.score as score, 
    , case when @prev_score = @curr_score then @rank := @rank 
     else @rank := (@curr_row + 1) -- <- this is what you require 
    end as rank 
    , @curr_row := (@curr_row + 1) as curr_row 
    , @prev_score := @curr_score 
FROM 
    score_users, 
    (SELECT @curr_score := 0, @prev_score := 0 
     , @curr_row := 0, @rank := 0) initializer 
WHERE 
    score_users.matchday = 1 
ORDER BY 
    score_users.score DESC 
संबंधित मुद्दे