2014-06-09 19 views
5

SQL'de yeniyim ve mysql'de hiçbir zaman değişkenler veya koşullar kullanmadım, ancak diğer programlama dillerinden biliyorum. Birkaç günden beri bir kullanıcı puanını sıralamak için bir yol bulmaya çalışıyorum. Çok fazla makale okudum ve ayrıca stackoverflow'ta sorulan soruları ve nihayetinde istediğim gibi bir çözüm buldum.MySQL İlişkili bağlar

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 

Ancak Sorunlarım, bağ puanlarıdır. Böyle, ardışık saflarına almak istemiyorum:

+------------+------+--------+ 
| 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 | 
+------------+------+--------+ 

Ben böyle bir sonuç almak istiyorum: ben yeni bir geçici tablo oluşturmak zorunda tahmin

+------------+------+--------+ 
| 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 | 
+------------+------+--------+ 

ve bazı şartlar var ama bir çözüm bulamadım ve çaresiz kaldım! Ayrıca, performansa dikkat etmeliyim, belki de yaptığım gibi sıralamasında daha iyi bir yol var mı? İpuçları veya bazı kod pasajları için çok minnettar olurum. Çok yerine 1 ile @rank artan aynı saflarına saymak için başka bir değişken kullanabilirsiniz

+0

Ben SQL dışında rank oluşturmak istiyorum yardımcı olmalıdır takiben. Yaptığını yapmak MySQL'de karmaşık! – serakfalcon

cevap

3

, böyle, sayaç değerine göre @rank artırır:

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

Teşekkürler Aziz, bu çok iyi çalışıyor. Sub select'te 1'e 1'e ayarladım, aksi halde sıralama 0 ile başladı! Şerefe – FredFus

0

hep artırılır başka rütbe alan ekleyin. Eğer değer eşleşirse, her zaman arttırılmış derecenizi kullanmazsanız, mevcut durumunuzu kullanırsınız (artırılmamış).

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

bağları üzerinde, atlayıp sonraki rütbe olarak bir sonraki eşsiz skor değer satırının mevcut satır num kullanmak isteyebilirsiniz. Eğer (skorla sıralama yeterlidir) kullandığınız ne olursa olsun programı ile yapmak daha kolay gibi, sen

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 
İlgili konular