IntroduzioneCome combinare queste due query per calcolare il cambio di classificazione?
Ho una tabella dei punteggi per il mio gioco che usa ranghi. La tabella dei punteggi rappresenta i punteggi più alti correnti e le informazioni sui giocatori e la tabella recente rappresenta tutti i punteggi pubblicati di recente da un utente che potrebbe avere o meno un nuovo miglior punteggio.
Il calo del punteggio viene calcolato calcolando il rango attuale del giocatore meno il rango che avevano al momento del raggiungimento dell'ultimo punteggio più alto.
L'aumento di rango viene calcolato calcolando il rango del giocatore che avevano al momento del raggiungimento del loro ultimo punteggio più alto meno il rango che avevano al momento del raggiungimento del punteggio superiore precedente.
Infine, come scritto in codice: $change = ($drop > 0 ? -$drop : $increase);
Domanda
Sto usando i seguenti due query combinate con un po 'di codice PHP per calcolare il cambiamento rango. Funziona perfettamente bene, ma a volte è un po 'lento.
Ci sarebbe un modo per ottimizzare o combinare le due query + codice PHP?
ho creato un violino SQL della prima query: http://sqlfiddle.com/#!9/30848/1
I tavoli sono pieni di contenuti già, quindi le loro strutture non devono essere modificate.
Questo è il codice di lavoro corrente:
$q = "
select
(
select
coalesce(
(
select count(distinct b.username)
from recent b
where
b.istopscore = 1 AND
(
(
b.score > a.score AND
b.time <= a.time
) OR
(
b.score = a.score AND
b.username != a.username AND
b.time < a.time
)
)
), 0) + 1 Rank
from scores a
where a.nickname = ?) as Rank,
t.time,
t.username,
t.score
from
scores t
WHERE t.nickname = ?
";
$r_time = 0;
if($stmt = $mysqli->prepare($q))
{
$stmt->bind_param('ss', $nick, $nick);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($r_rank, $r_time, $r_username, $r_score);
$stmt->fetch();
if(intval($r_rank) > 99999)
$r_rank = 99999;
$stmt->close();
}
// Previous Rank
$r_prevrank = -1;
if($r_rank > -1)
{
$q = "
select
coalesce(
(
select count(distinct b.username)
from recent b
where
b.istopscore = 1 AND
(
(
b.score > a.score AND
b.time <= a.time
) OR
(
b.score = a.score AND
b.username != a.username AND
b.time < a.time
)
)
), 0) + 1 Rank
from recent a
where a.username = ? and a.time < ? and a.score < ?
order by score desc limit 1";
if($stmt = $mysqli->prepare($q))
{
$time_minus_one = ($r_time - 1);
$stmt->bind_param('sii', $r_username, $time_minus_one, $r_score);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($r_prevrank);
$stmt->fetch();
if(intval($r_prevrank) > 99999)
$r_prevrank = 99999;
$stmt->close();
}
$drop = ($current_rank - $r_rank);
$drop = ($drop > 0 ? $drop : 0);
$increase = $r_prevrank - $r_rank;
$increase = ($increase > 0 ? $increase : 0);
//$change = $increase - $drop;
$change = ($drop > 0 ? -$drop : $increase);
}
return $change;
Forse passare a PDO lo rende un po 'più veloce, ma probabilmente non farà nulla. – Tom
Potresti spiegare: – gfunk
Potresti definire 1. quali sono le due tabelle e 2. qual è il tuo algoritmo/matematica per il calcolo del rank? Da quello che ho capito il mio grado è il numero di voci recenti di altre persone che hanno ottenuto un punteggio più alto * e * avvenuto prima (in tempo) del mio record nella tabella "punteggi". più ignorando! istopscoes – gfunk