mysql ORDER BY

Alessandro Le Mura

Utente Attivo
28 Apr 2013
74
0
0
www.glaucusgames.com
Raga ho questa query che sto cercando di utilizzare per mettere in ordine una classifica in base alla media voti, come posso fare a sostituire questo pezzo:

Codice:
mysql_query("SELECT nomegiocovoti, paginavoti, COUNT(rate) AS num_voti, SUM(rate) AS totvoti FROM voti GROUP BY nomegiocovoti ORDER BY [COLOR="#FF0000"](somma voti diviso totale numero voti) totvoti/num_voti[/COLOR] DESC LIMIT 0, 1");
 
aggiunta

PHP:
mysql_query("SELECT nomegiocovoti, paginavoti, COUNT(rate) AS num_voti, SUM(rate) AS totvoti FROM voti GROUP BY nomegiocovoti ORDER BY totvoti DESC LIMIT 0, 1");

   while($rigavoti=mysql_fetch_array($queryvoti)){
        $nomegiocovoti = $rigavoti['nomegiocovoti'];
        $paginavoti = $rigavoti['paginavoti'];
        $totvoti = $rigavoti['totvoti'];				
        $num_voti = $rigavoti['num_voti'];
        $media = $totvoti / $num_voti; //[COLOR="#FF0000"]<---- Così ho ottenuto la media, ora dovrei creare un'altra query x mettere in ordine x media xò xke prima la variabile $media nn esisteva, solo ke nn riesco a farla funzionare dannazione, forse xke la nuova query la creo dentro while[/COLOR]
				
        echo "<table class=\"tabellaclassifica\"><tr><td align=\"left\"><b><font color=\"#08088A\">1 &nbsp;</font></b><a href=\"$paginavoti\" title=\"Play $nomegiocovoti on Glaucusgames\">$nomegiocovoti</a></td>";
        echo "<td>";
	echo 'Rating: '.round($media,2) .'/5';
	echo "</td></tr>";
		    }
 
Ultima modifica di un moderatore:
ciao
perche devi creare un'altra query? prova così
PHP:
<?php
//....
while($rigavoti=mysql_fetch_array($queryvoti)){
	$nomegiocovoti = $rigavoti['nomegiocovoti'];
	$paginavoti = $rigavoti['paginavoti'];
	$totvoti = $rigavoti['totvoti'];
	$num_voti = $rigavoti['num_voti'];
	//occhio qui, se num voti è 0 o vuoto ti va in tilt lo script
	if($num_voti > 0){
		//concatenando ti porti dietro anche il nome della paginavoti
		$media[$nomegiocovoti] = round($totvoti / $num_voti,2)."|$paginavoti";
	}else{
		$media[$nomegiocovoti]=0"|$paginavoti";
	}
}
arsort($media);
echo "<table class=\"tabellaclassifica\">";
foreach($media as $gioco => $m){
	$ex=explode("|",$m);//ridividi la media dal nome paginavoti
	echo "<tr><td align=\"left\"><b><font color=\"#08088A\">1 &nbsp;</font></b><a href=\"".$ex[1]."\" title=\"Play $gioco on Glaucusgames\">$gioco</a></td>";
	echo "<td>Rating: ".$ex[0]."</td></tr>";//cosa è quel '/5' slash cinque?
}
echo "</table>";
//.....
?>

p.s.
racchiudi il codice con gli appositi tag
 
geniale

Un genio, nn avevo pensato a sort, credo di aver capito cosa vuoi dire, appena posso provo, mi risparmi anke un sacco di righe di codice col foreach, se sai il casino ke ho fatto xD ahah grazie mille, ti faccio sapere cm è andata appena ho tempo x implementarlo
 
modifiche..

PHP:
		$queryvoti = mysql_query("SELECT nomegiocovoti, paginavoti, COUNT(rate) AS num_voti, SUM(rate) AS totvoti FROM voti GROUP BY nomegiocovoti DESC LIMIT 0, 10");

    while($rigavoti=mysql_fetch_array($queryvoti)){
		    $nomegiocovoti = $rigavoti['nomegiocovoti'];
        $paginavoti = $rigavoti['paginavoti'];
        $totvoti = $rigavoti['totvoti'];				
        $num_voti = $rigavoti['num_voti'];
				    //occhio qui, se num voti è 0 o vuoto ti va in tilt lo script
    if($num_voti > 0){
        //concatenando ti porti dietro anche il nome della paginavoti
        $media[$nomegiocovoti]= round($totvoti / $num_voti,2);
    }else{
        $media[$nomegiocovoti]= 0;
    }
}
arsort($media);
echo "<table class=\"tabellaclassifica\">";
foreach($media as $nomegiocovoti => $m){
    $ex=explode("|",$m);//ridividi la media dal nome paginavoti
    echo "<tr><td align=\"left\"><b><font color=\"#08088A\">1 &nbsp;</font></b><a href=\"".$ex[1]."\" title=\"Play $nomegiocovoti on Glaucusgames\">$nomegiocovoti</a></td>";
    echo "<td>Rating: ".$ex[0]."</td></tr>";//cosa è quel '/5' slash cinque?
}
echo "</table>";

CODICE AGGIORNATO:
Ho modificato qualkosina e ora funziona, è sorto un nuovo problema.. Praticamente prende da MYSQL un campione di 10 giochi su 30, quelli con la lettera più bassa, e li mette in ordine x media e stampa..
A me servirebbe ovviamente ke fa la media di tt i giochi e li stampa in ordine, forse è qlks ke riguarda qst pezzo: GROUP BY nomegiocovoti DESC LIMIT 0, 10?? Ho fatto qlk prova ma nada
 
Ultima modifica di un moderatore:
ciao
se vuoi prenderli tutti elimina dalla query LIMIT 0, 10
poi una piccola cosa: è un errore di copy/paste o ti sei dimenticato di mettere il concatenamento?
perchè se non fai il concatenamento $ex=explode("|",$m); non funzia come dovrebbe
 
Codice:
        //concatenando ti porti dietro anche il nome della paginavoti
        $media[$nomegiocovoti] = round($totvoti / $num_voti,2)."|$paginavoti";
    }else{
        $media[$nomegiocovoti]=0"|$paginavoti";
Dici questa parte di concatenamento?

Comunque il LIMIT ---- FROM voti GROUP BY nomegiocovoti DESC LIMIT 0, 10 ---- c'è messo xke devo stampare solo 10 giochi praticamente in classifica, la top 10 più votati, solo ke così facendo mi stampa i primi 10 e funziona si, ma i primi 10 delle ultime lettere dell'alfabeto, e qst è causato penso da GROUP BY nomegiocovoti, qst problema dovrei risolvere capito?
 
ciao
si dicevo quella.
poi prova così
PHP:
<?php
//...
$queryvoti = mysql_query("SELECT nomegiocovoti, paginavoti, COUNT(rate) AS num_voti, SUM(rate) AS totvoti FROM voti GROUP BY nomegiocovoti ORDER BY rate, nomegiocovoti DESC LIMIT 0, 10");
//...
?>
se funzia ok, altrimenti devo pensarci.
 
niente da fare.. Cioè funziona ma non è giusta la classifica, NON ci sono i primi 10 giochi più votati, ci sono 10 giochi messi in ordine dal più votato al meno votato.. Ma come si potrebbe fare, nn si può mettere direttamente in GROUP BY media e ORDER BY $media?
 
Perchè non usi direttamente average (media)?
Codice:
SELECT nomegiocovoti, paginavoti, AVG(rate) AS media FROM voti GROUP BY nomegiocovoti ORDER BY media DESC LIMIT 0, 10");
 
ciao
mi viene un dubbio
quando uno vota cosa succede?

esempio:
l'utente pinco vota tresette
a) da una valutazione es da 0 a 9? o b) il voto è uno?
caso a)
si crea il record
Codice:
id | gioco | rate
1 | tresette | 2
l'utente pallo vota ancora tresette
a.1) si creaa il record
Codice:
id | gioco | rate
1 | tresette | 2
2 | tresette | 3
media[tresette] = (2+3)/2 = 2.5
a.2) oppure il primo record si uppa
Codice:
1 | tresette | 5
media[tresette] = 5/1 = 5 (assurdo)

caso b)
si crea il record
Codice:
id | gioco | rate
1 | tresette | 1
l'utente pallo vota ancora tresette
a.1) si creaa il record
Codice:
id | gioco | rate
1 | tresette | 1
2 | tresette | 1
media[tresette] = (1+1)/2 = 1 e sempre uno (assurdo)
a.2) oppure il primo record si uppa
Codice:
1 | tresette | 2
media[tresette] = 2/1 = 2 (assurdo)

dovresti saper dire come avviene la votazione, perchè mi sbaglierò, ma è da ripensare il tutto
 
Perchè non usi direttamente average (media)?
Codice:
SELECT nomegiocovoti, paginavoti, AVG(rate) AS media FROM voti GROUP BY nomegiocovoti ORDER BY media DESC LIMIT 0, 10");

Xk nn sapevo ke esistesse il comando average xD sn un dilettante, so a malapena creare il database e fargli memorizzare e leggere i dati..
Ora ci provo e ti faccio sapere, grazie


X BORGOITALIA:

Tabella mysql:

nomegiocovoti paginavoti ip rate

G-Switch /games/action/g-switch.php 118.93.190.197 5
Bubble Struggle 2 /games/puzzle/bubblestruggle2.php 122.163.203.23 1
G-Switch /games/action/g-switch.php 125.236.44.44 3
Swordless Ninja /games/adventure/swordlessninja.php 125.60.156.148 1
Pirateers /games/rpg/pirateers.php 151.54.136.109 3
Days2die /games/zombie/days2die.php 151.54.136.109 4

1 volta ogni 24 ore uno stesso IP può rivotare uno stesso gioco, ma il suo voto andrà ad aggiungersi e non a sostituirsi, i voti vanno da 1 a 5
 
Ultima modifica:
ciao
avg in questo caso non ti serve.
avg di da la media (sballata) di tutta la colonna e non suddivisa per gioco.
sballata in quanto ti da la media calcolata con la somma dei valori del campo diviso il numero di record, ma da quello che ho capito tu vuoi calcolare in base a quanti voti, ti faccio un esempio
id | voto | votanti
1 | 5 | 3
2 | 4 | 1
con avg media =(5+4)/2 che è diversa dal voto medio = (5+4)/(3+1)

primo consiglio
aggiungi un campo int (es num_voti) che alla votazione si uppa ....num_voti=num_voti+1
volendo anche un campo media che sempre alla votazione si uppa
in questo modo risolvi tutti i tuoi problemi

una domanda:
ho visto la tabella, ma il campo nomegiocovoti in pratica è unico? se si a che ti serve il group by?
 
AVERAGE infatti nn funzia..

Il GROUP BY nn so xk l'ho messo, stavo smanettando il codice in cerca di una soluzione e lo avevo inserito x qlk oscuro motivo ke ora neanke ricordo x mettere in ordine i giochi boh.. ma nn credo ke serva..
Per quanto riguarda il campo "nomegiocovoti" no non è unico.

Onestamente avevo pensato alla soluzione del campo, ma pensavo ci fosse un modo x evitarla, anke se credo ke la soluzione più pulita e migliore è proprio qst ke stai dicendo del campo..
Il problema è ke creo più campi xke devo memorizzare gli IP delle persone ke votano x far si ke non rivotino, se faccio il campo cn update come faccio a memorizzare tt gli IP?

ps.: se tolgo il pezzo GROUP BY nomegiocovoti mi stampa a video 1 record solo al posto dei 10 record
 
ciao
dai un occhio a questo schema, come secondo me dovresti fare la pagina che registra i voti.
come ti avevo detto farei una tabella per il rilevo degli ip e modificherei la tabella voti
comunque dai un occhio, eventualmente provala mettendola un po' a posto
PHP:
<?php
/*farei la tabella "votato"
id int(6) autoincrement pronaykey
tempo int(13)
ip varchar(25)
*/
//qui non so come prelevi la votazione, faccio finta che siano due post
$voto=$_POST['voto'];
$gioco=$_POST['nome_gioco'];
// prelevi l'ip di chi vota
$ip=$_SERVER['HTTP_REFERER'];
//e il momento del voto
$adesso=time();
//fai la select sulla tabella votato
$q=mysql_query("SELECT * FROM votato WHERE ip='$ip'");
//tre casi: l'ip non ha mai votato, ha votato e sono trascorse + di 24 ore, ha votatao e NON sono trascorse 24 ore
$permesso="";
if(mysql_num_rows($q) == 0){//l'ip non esiste
	$permesso="SI";//autorizzo a votare e inserisco in tabella
	$qi=mysql_query("INSERT INTO votato(tempo, ip) VALUES($adesso,'$ip')");
}else{//esiste e quindi controllo quando ha votato
	$riga=mysql_fetch_array($q);
	$ultimo_voto=$riga['tempo'];
	//calcolo ore
	$trascorse=($adesso-$ultimo_voto)/3600;//trasformo il tempo in ore
	if($trascorse > 24){//trascorse più di 24 ore
		$permesso="SI";
		//uppo il record per qull'ip
		$qu=mysql_query("UPDATE votato SET tempo= $adesso WHERE ip='$ip'");
	}else{//trascorse meno di 24 ore
		$permesso="NO";
	}
}
/*poi modificherei la tabella voti dove hai i giochi aggiungendo/modificando i campi
...nome_gioco (varchar), votazione (int), num_voti (int), media (float)
provando a fare una cosa del genere
*/
if($permesso="SI"){//l'utente puo votare
	//verifico se esiste già il record
	$q=mysql_query("SELECT * FROM voti WHERE nome_gioco='$gioco'");
	if(mysql_num_rows($q)){//il record non esiste (metto i ... se hai altri campi)
		//la media in questo caso è ugguale al voto = voto/1=voto
		$qi=mysql_query("INSERT INTO voti(...,nome_gioco, votazione, num_voti, media,...) VALUES(...,'$gioco',$voto, 1, $voto,...)");
	}else{//il record esiste di gia quindi lo uppi
		//faccio i calcoli, ma forse si possono fare direttamente nella query
		$riga=mysql_fetch_array($q);
		$somma_voti=$riga['votazione']+$voto;
		$numero = $riga['num_voti']+1;
		$media=$somma_voti/$numero;
		$qu=mysql_query("UPDATE voti SET votazione=$somma_voti, num_voti=$numero, media=$media WHERE nome_gioco='$gioco'"); 
	
	}
}else{
	echo "non sono passate ancora 24 ore dall'ultimo tuo voto";
}
//.......
?>
in questo modo nel record hai tutti i dati che ti servono per fare tutte le estrazioni che vuoi

p.s.
in automatico puoi fart in questa stessa pagina un delete della tabella votato eliminando i record più vecchi es. di tre gg, in questo modo non riempi inutilmente la tabella

ps al ps
qui ho usato le vecchie query per fare prima, ma ti conviene passare a mysqli o meglio alla pdo.
 
Ho risolto tutto con l'array_slice e il pezzo di codice che mi avevi dato tu, sembra funzionare alla grande adesso, e nella query ho tolto il DESC LIMIT

Codice:
foreach(array_slice($media, 0, 10) as $nomegiocovoti => $m){
    $ex=explode("|",$m);
    echo "<tr><td align=\"left\"><b><font color=\"#08088A\">1 &nbsp;</font></b><a href=\"".$ex[1]."\" title=\"Play $nomegiocovoti on Glaucusgames\">$nomegiocovoti</a></td>";
    echo "<td>Rating: ".$ex[0]."</td></tr>";
}
 

Discussioni simili