Visualizzazione risultati 1 fino 10 di 10

Discussione: assegnazione variabili

  1. #1
    Guest

    Predefinito assegnazione variabili

    Ho un problema con una interrogazione nell'assegnazione di variabili secondo questo schema:
    // dichiaro le variabili @giocatore e @num che mi serve per recuperare i migliori 10 risultati//
    set @giocatore:=0, @num:=1;

    //con questa query invece controllo se la variabile @giocatore che ho assegnato sia uguale al campo giocatore se è uguale incrementa di uno la variabile @num e il ciclo continua fino a verificare che la variabile arrivi a 10 per escludere gli altri risulati e poi ricomincia con il successivo giocatore//
    select codice,giocatore,(round((sum(score)/10),2)) as media ,nome_giocatore as nome,(count(*))as tornei ,min(score) minimo from (select *,@num := if(@giocatore = giocatore, @num + 1, 1) as riga_numero,@giocatore := giocatore as id from (select id_giocatore as giocatore , score,n_granprix,data,cod_giocatore as codice,id as indice from ojg69_qs_gp where n_granprix =1 and cod_gp =1 and YEAR(data) =2016 order by giocatore , score desc) as tab)as tab2 left join ojg69_qs_giocatori g on g.id = giocatore where riga_numero <=10 group by giocatore order by media desc;

    La query funzionava fino a poco fa ma da quando uso la versione MySQL: 5.5.44-MariaDB non fa più il calcolo dei solo 10 risultati ma li mette tutti, credo non assegna le variabili con il comando set o non so bene come mai. Spero ci sia qualcuno che possa darmi una mano per capire cosa non va sono disponibili per chierimenti più precisi su tutto. Grazie
    Ultima modifica di binaghilab : 18-03-2016 alle ore 20.41.21

  2. #2
    Guest

    Predefinito

    Ho pensato di riformulare la richiesta di aiuto cercando di limitarmi nelle spiegazione ai fatti più importanti:
    1)Da poco il mio provider ha aggiornato il server e da quando è successo una query che prima regolarmente funzionava ora non fa più il suo lavoro.
    2) la query è la seguente:
    set @giocatore:=0, @num:=1;
    select count(@num) as variabile, codice, id_giocatore,(round((sum(score)/10),2)) as media,count(*)as tornei from (select *,@num := if(@giocatore = id_giocatore,@num + 1,1) as riga_numero,(@giocatore := id_giocatore) from (select id_giocatore , score,cod_giocatore as codice from ojg69_qs_gp where n_granprix =1 and cod_gp =1 and YEAR(data) =2016 order by cod_giocatore , score desc) as tab)as tab2 where riga_numero <= 10 group by codice order by media desc;.
    3) Quando la eseguo lato admin in locale con phpMyAdmin 4.0.4.1 ottengo il risultato corretto,
    mi fa la media dei migliori 10 risultati.
    Quando invece eseguo la stessa query lato server con phpMyAdmin 4.5.5 ottengo la somma di tutti i risultati diviso 10 che non è piu media.
    Qualcuno sa cosa posso fare di concreto, eventualmente riformulare l'interrogazione.
    Anticipatamente ringrazio

  3. #3
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,954

    Predefinito

    La query è piuttosto articolata, non è immediato capire cosa dovrebbe fare !
    Mi domando se non esista un modo più semplice di formularla, magari evitando del tutto l'uso delle variabili.

    Qual'è lo scopo dell'interrogazione, spiegato a parole?

  4. #4
    Guest

    Predefinito

    Ripartiamo da zero. Ho la necessita di ottenere la media dei migliori 10 risultati di ogni giocatore che partecipa a un torneo composto da 13 gare.
    La tabella sintetizzando potrebbe essere cosi articolate:
    Id_giocatore int
    Punteggio varchar
    Giocatore varchar
    Domanda: Si può ottenere questa lista senza l’uso di variabili? O anche con le variabili, ma diversamente da come le avevo impostate io?
    Ringrazio tutti quelli che possono aiutarmi.

  5. #5
    darbula non è connesso AlterGuru 2500
    Data registrazione
    24-04-2011
    Messaggi
    2,894

    Predefinito

    Scusami la domanda seguente è questa. ci sono più Id_giocatore con lo stesso int? (perché non hai fatto una somma tot per il punteggio,è un campo per quella gara con tutti i giocatori al torneo per quel giocatore [dove sconfitte,pareggi,vittorie siglate a questo modo io sono Id_giocatore =1 è ho perso con Id_giocatore = 2 's0' se avessi pareggiato 'p1']) di conseguenza hai 13 volte (gare disputate) con Id_giocatore uguale.
    La logica sarebbe di recuperare l'Id_giocatore iniziando dal più basso, estrarre i 10 migliori punteggi sommarlo e calcolare una media (cioè a dire la somma diviso 10).
    Ultima modifica di darbula : 20-03-2016 alle ore 13.52.11

  6. #6
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,954

    Predefinito

    Se ho capito bene, vuoi ottenere una relazione che associ, a ciascuno dei giocatori iscritti al torneo, la media dei 10 punteggi più alti ottenuti da quel giocatore.

    L'opzione più semplice probabilmente è effettuare una query per ogni giocatore (ho assunto che la tabella da te descritta si chiami "gara"):
    Codice:
    SELECT AVG(Punteggio) FROM (SELECT Punteggio FROM gara WHERE Id_giocatore = :id ORDER BY Punteggio DESC LIMIT 10) AS punteggi;
    Per comodità (e come suggerimento) ho usato la sintassi di un prepared statement. Eseguendolo tante volte quanti sono i giocatori, ogni volta con l'identificatore appropriato, ottieni il risultato richiesto.
    Lo svantaggio è nel numero di interrogazioni, che sono proporzionali al numero di giocatori, ma se questo numero è contenuto (ordine delle decine) e vengono usati prepared statements e la stessa connessione, non credo ci siano impatti negativi sulle prestazioni.

    Se, per qualunque motivo, hai necessità di recuperare tutti i dati in un'unica interrogazione, potresti recuperare i punteggi di tutte le gare di tutti i giocatori ed elaborarli in un secondo momento con PHP (o qualunque linguaggio tu stia usando).

    In alternativa, puoi sempre ristrutturare la base di dati in modo da rendere quest'interrogazione più semplice, operazione costosa ma che può portare benefici nel lungo termine.

  7. #7
    Guest

    Predefinito

    Per prima cosa ringrazio dei suggerimenti. Rispondo in ordine cronologico primo a darbula: la graduatoria e creata con i risultati di 13 tornei nei quali partecipano circa 110 giocatori che possono partecipare a N tornei senza vincolo di partecipazione. Come da regolamento si calcolo la media con i migliori 10 risultati scartando quelli più bassi, tutto questo si fa per ogni giocatore che ha un suo id univoco. Rispondo al secondo mzanella: Uso PHP come linguaggio server. La query proposta esegue il calcolo corretto, ma poi come ottengo l'elenco dei giocatori ordinati per valore media punteggio decrescente che poi utilizzerò per recuperare i dati filtrandoli (Id_giocatore:= $id)? Potrei creare un array con i valori a caso ma non so come ordinarli? A suo tempo, circa 8 anni fa, avevo pensato anch'io a questa soluzione ma non trovavo il modo di ottenere la lista e in forum mi avevano proposto la query, rielaborata, che ho usato fino all'altro giorno che fungeva al mio scopo egregiamente. Cmq se riesco ad ottenere la lista, cosi come mi consigli, poi il gioco e fatto in quanto sono circa 120 giocatori da scorre.
    Ringrazio tutti voi, spero di essere stato chiaro. A vostra disposizione

  8. #8
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,954

    Predefinito

    Usando la query del messaggio precedente sei in grado di produrre un vettore in cui ogni elemento rappresenta un giocatore con relativo punteggio medio.

    Una volta ottenuta questa lista, puoi definire una funzione di confronto ed utilizzare usort:
    Codice PHP:
    function player_compare($a, $b) {
    return
    $b->avg_score - $a->avg_score;
    }
    ...
    $players = array(...);
    usort($players, 'player_compare');
    Se non hai una classe Giocatore puoi ottenere lo stesso effetto usando i vettori associativi di PHP:
    Codice PHP:
    function player_compare($a, $b) {
    return
    $b['avg_score'] - $a['avg_score'];
    }


    // Just an example, you will use queries to populate this array
    $players = array(
    array(
    'id' => 5, 'avg_score' => 42);
    array(
    'id' => 7, 'avg_score' => 7);
    ...
    );
    ...
    usort($playes, 'player_compare');
    Costruire il vettore iniziale $players non dovrebbe essere un problema, usando la query, ma se ci sono dubbi siamo qui apposta .

  9. #9
    Guest

    Predefinito

    Grazie mzanella analizzo la funzione e vedo di applicarla al contesto, poi farò sapere se tutto ok

  10. #10
    Guest

    Predefinito

    Provato e funziona. Ringrazio vivamente mzanella.
    Ho impiegato un po per arrivare a questo listato che riassumo cosi:

    //eseguo una query per recuperare la lista dei giocatori del Grand Prix ,
    query
    //dichiaro l'array
    &graduatoria=array();

    //poi con un ciclo while inizio a caricare i dati nell'array
    while ($mul < count($totali))
    {
    //ad ogni passaggio formulo la query suggerita da mzanella per ogni giocatore, adattandola al mio contesto.
    query
    //carico l'array.
    $graduatoria[$mzanella[0]['cod_giocatore']]=$mzanella[0]['percento'];
    $mul++;
    }

    //ho trovato questo funzione che ordina un array in ordine decrescente e mantiene le associazioni degli indici.
    arsort($graduatoria);

    //scorro la lista e la stampo per verificare la sua riuscita e funge.
    foreach($graduatoria as $key=>$valore)
    {
    echo $key."-".$valore."/";
    }
    Spero di essere stato chiaro. Un ringraziamento ad mzanulla per il suo grande aiuto.

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •