- Home
- Categorie
- Coding e Sistemistica
- Coding
- query incrociata per classifiche personali
-
Ok, in questo caso però non ho fatto altro che ottenere tutti i giochi ai quali ha giocato IDUTENTE ... non c'è bisogno di fare un LEFT JOIN perchè se è vero che conosco l'id mi basta fare:
SELECT gioco, punteggio
FROM tbl_punteggi
WHERE nick = $nick
e ottengo lo stesso risultato.La cosa bella sarebbe determinare in che posizione è l'utente rispetto agli altri. Mi sembra strano che debba fare tante query quante sono i giochi.
Ti ringrazio per l'aiuto e non vorrei abusare della tua gentilezza, quindi fermati quando vuoi
Grazie ancora
-
@Bukowski said:
La cosa bella sarebbe determinare in che posizione è l'utente rispetto agli altri. Mi sembra strano che debba fare tante query quante sono i giochi.
Io userei
SELECT nick, gioco, punteggio
FROM nome_tabella_account
LEFT JOIN nome_tabella_punteggi
ON iduser = idnick
WHERE iduser = <id_dell'utente>(cosi' avresti anche il nick... altrimenti puoi usare la tua query, ma il nick deve saltare fuori in altro modo)
Poi per la posizione
SELECT COUNT(*) FROM tbl_punteggi WHERE punteggio > <punteggio_utente> (lo passi via PHP)altrimenti se hai a disposizione una versione MySQl che supporta subqueries (> 4.1)
SELECT COUNT(*) FROM tbl_punteggi WHERE punteggio > (SELECT punteggio FROM tbl_punteggi WHERE iduser = <id_dell'utente>)Una cosa del genere dovrebbe funzionare
ciao
-
Ok mi metto subito all'opera.
Grazie ancora per il prezioso supporto.
-
Allora secondo me ci siamo molto vicini, però non capisco una cosa ... dovrei fare tante query quanti sono i giochi per contare la posizione?
Con questa query tiro fuori, di un determinato utente, tutti i giochi e i punteggi realizzati:
SELECT nickpt, giocopt, puntipt
FROM mp_classifiche WHERE nickpt= '$user';
il risultato è giustamente:
| BUKOWSKI | ARKANOID | 100.000 |
| BUKOWSKI | FLIPPER | 755.000
ecc ecc.E' l'altra che non so dove e come applicarla
Poi per la posizione
SELECT COUNT(*) FROM tbl_punteggi WHERE punteggio > <punteggio_utente> (lo passi via PHP)Si ripeterà nel ciclo while di ogni riga per ogni gioco??
Grazie ancora
(Purtroppo ho del mysql la 4.0)
-
Ci sono diversi metodi per affrontare il problema.
Per esempio:
preso un utente fai una query che ottenga nick, gioco e punteggio e le conservi in alcune variabili. Poi all'interno del loop chiami la querySELECT COUNT(*) FROM tbl_punteggi WHERE punteggio > <punteggio_utente> AND gioco = <gioco>
e poi mandi in stampa tutto quello che ti serve.
-
@nessuno said:
Ci sono diversi metodi per affrontare il problema.
Per esempio:
preso un utente fai una query che ottenga nick, gioco e punteggio e le conservi in alcune variabili. Poi all'interno del loop chiami la querySELECT COUNT(*) FROM tbl_punteggi WHERE punteggio > <punteggio_utente> AND gioco = <gioco>
e poi mandi in stampa tutto quello che ti serve.
ok .. quindi però mi ritrovo ad avere tante query quante sono i giochi per quel determinato utente .. ovvero 40 ...
ho paura che ritorno ad una situazione di pesantezza della query.
-
Come ti dicevo prima ci sono sicuramente molti altri modi di affrontare questo problema, alcuni radicalmente diversi.
IMHO anche 40 queries di quel tipo (vedi successivi commenti) non sono particolamente pesanti se il server e' correttamente dimensionato; sarebbero molto peggio un numero di queries inferiori ma molto piu' complicate.
Ci sono altre valutazioni da fare sulla struttura del database e sull'ottimizzazione delle queries.
Ti posto in seguito alcuni commenti.
-
Per quanto riguarda la struttura del database
@Bukowski said:
In pratica ho 2 tabelle:
# TABELLA ACCOUNT (20.000 record)- Qui ci sono i dati di registrazione dell'utente
| iduser | nick | pwd
esempio: 5 | Bukowski | peppino
**# TABELLA PUNTEGGI ** (90.000 record)
- Qui registro i punteggi fatti da ogni utente in ogni gioco
| nickpt | gioco | punteggio | data
esempio: | Bukowski | Arkanoid | 34000 | 12-12-2005
esempio: | Nessuno | Flipper | 15000 | 10-12-2005
In accordo con le regole di [url=http://it.wikipedia.org/wiki/Normalizzazione_del_database]normalizzazione di un database, in particolare, in questo caso, la Seconda Forma Normale, la tabella tbl_punteggi andrebbe scomposta in due tabelle con la seguente struttura:
tbl_punteggi
| nickpt | gioco_id | punteggio | data (assumo che nickpt sia un indice che si riferisce alla tabella degli utenti)tbl_giochi
gioco_id | gioco_nameQuesto implica un serie notevole di vantaggi:
- nella clausola WHERE non metti un nome ma un numero per cui la query richiede meno elaborazione, per cui termina piu' rapidamente.
- nei 90000 records della tbl_punteggi avrai solamente dei numeri (tinyint da 1 byte possibilmente) invece che lettere (VARCHAR da 8 + 1 byte nel caso di Arkanoid)
- se vuoi cambiare un nome di un gioco, lo cambi una sola volta e non in tutte le sue occorrenze fra quelle 90000 righe
- e in ultimo... si fa cosi' ; )
- Qui ci sono i dati di registrazione dell'utente
-
Con la struttura definita come nel precedente messaggio, sarebbe utile avere degli indici su:
tbl_account.iduser (PRI)
tbl_giochi.gioco_id (PRI)
tbl_punteggi.nickpt (INDEX)
tbl_punteggi.gioco_id (INDEX)Eventualmente io consiglierei di utilizzare tabelle INNODB e settare le foreign_keys.
In questa maniera tutte le join verrebbero fatte su dei campi indicizzati per cui il carico elaborativo sarebbe minimo.
Ulteriori ottimizzazioni potrebbero essere ottenute scegliendo adeguatamente i tipi di dati di ogni campo.
Se posti l'output di un
DESCRIBE nome_tabella
oppure SHOW CREATE nome_tabella
ti posso dare maggiori dettagli
-
Accidenti, mi ero perso il proseguio di questo post ....
io devo mettermi a studiare perchè quello di cui hai scritto ho capito il 70%.
A questo punto se dici che è meglio avere degli INT potrei trasformare la tabella punteggi in
IDNICK (ora c'è il nome!) | IDGIOCO | PUNTEGGIO
es: 6 | 9 | 54.000e quindi avere una tabella che riporta i nomi dei giochi
IDGIOCO | NOMEGIOCO
es: 1 | ArkanoidE' anche vero che cosi facendo mi troverò costretto a più parti a ricorrere a dei JOIN sia per ricavare il nome del gioco che il nick del giocatore.
Giusto?
-
@Bukowski said:
E' anche vero che cosi facendo mi troverò costretto a più parti a ricorrere a dei JOIN sia per ricavare il nome del gioco che il nick del giocatore.
Giusto?
Si, ma ma avrai un database fatto secondo le regole e le prestazioni saranno superiori.
E considera che le join su un database cosi' semplice sono un banalita'.