2014-06-09 14 views
5

Sono nuovo in sql e non ho mai usato variabili o condizioni in mysql, ma lo so da altri linguaggi di programmazione. Da alcuni giorni cerco di trovare un modo per classificare un punteggio utente. Ho letto molti articoli e anche domande che mi hanno chiesto su StackOverflow e alla fine ho trovato una soluzione che quasi mi piace.MySQL Rank con legami

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 

Ma i miei problemi sono punteggi cravatta. Non voglio ottenere ranghi consecutivi, in questo modo:

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

vorrei ottenere un risultato simile a questo:

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

mi sa che devo creare una nuova tabella temporanea, e un po ' se le condizioni, ma non riuscivo a trovare una soluzione e diventare disperato! Inoltre, devo tenere d'occhio le prestazioni, forse ci sono modi migliori per ottenere il punteggio nel punteggio come ho fatto io? Sarei molto grato per i suggerimenti o qualche frammento di codice.

+0

mi piacerebbe generare il rango di fuori del SQL, come è più facile a che fare con qualunque programma che si sta utilizzando (classifica per punteggio è abbastanza). Fare quello che stai facendo è complicato in MySQL! – serakfalcon

risposta

3

È possibile utilizzare un'altra variabile per contare gli stessi ranghi così invece di incrementare @rank da 1, si incrementa @rank dal valore del contatore, in questo modo:

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

Grazie Aziz, questo funziona molto bene. Ho appena impostato @rank su 1 nella selezione secondaria, altrimenti la classifica è iniziata con uno 0! Saluti – FredFus

0

aggiungere un altro campo rango che è sempre incrementato. Se il valore corrisponde a te, usa il tuo rango esistente (non incrementato), altrimenti non usi il tuo rango sempre incrementato.

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

su legami, si consiglia di saltare e utilizzare corrente num riga alla riga successiva valore di punteggio impareggiabile come grado successivo. seguito dovrebbe aiutare a

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