mysql query, sum(qualcosa), order by sum(qualcosa). E' possibile?

gandalf1959

Utente Attivo
21 Nov 2013
208
1
18
Buongiorno a tutti,
ho una tabella che contiene i dati degli isccritti a lezioni di cucina e mi serve ottenere un elenco delle lezioni e per ciascuna lezione il totale degli iscritti. Naturalmente da una pagina .php
La query che utilizzo è
Codice:
$query = ("SELECT *, sum(postiprenotati) FROM `utentiscuola` GROUP BY id_lezione ORDER BY id_lezione");
E funziona.
Però non riesco ad ordinare la lista in base alla somma degli utenti. E' possibile?
Mettendo ...ORDER BY sum(postiprenotati) non funziona, naturalmente...
Qualche suggerimento?
Grazie
 

cris8380

Moderatore
Membro dello Staff
MOD
3 Giu 2016
261
14
18
40
Prova così
PHP:
$query = "SELECT * FROM utentiscuola WERE sum ORDER BY  * ASC";
 

marino51

Utente Attivo
28 Feb 2013
3.203
207
63
Lombardia
scusami, ma la query del primo post non può funzionare, perché,

nella clausola group by devono essere elencati tutti gli elementi non raggruppati,

indicando "*" nella select, si presuppone che debba restituire più colonne, che giustappunto non sono elencate nella group by

supponendo che la tabella contenga solo le colonne "id_lezione" e "postiprenotati", ti restituirebbe, per via dell'asterisco
esattamente le due colonne (dettaglio massimo) e poi dovrebbe fare la somma, di cosa ?

quando si usa la clausola group by, è normale specificare, al posto dell'asterisco, l'elenco delle colonne che definiscono il raggruppamento e poi le colonne raggruppate,
le colonne che definiscono il raggruppamento sono poi elencate nella clausola group by
Codice:
$query = "SELECT id_lezione, sum(postiprenotati) FROM utentiscuola GROUP BY id_lezione ORDER BY id_lezione";
Codice:
$query = "SELECT id_lezione, sum(postiprenotati) FROM utentiscuola GROUP BY id_lezione ORDER BY sum(postiprenotati), id_lezione";
 

gandalf1959

Utente Attivo
21 Nov 2013
208
1
18
Ho capito, grazie. In effetti adesso ho esattamente il risultato che mi aspettavo.
E ho imparato qualcos'altro, come sempre!
Nel frattempo ho un'altra cosa che non capisco e ne approfitto:
Oltre al codice della lezione, devo visualizzarne il titolo, che si trova in un'altra tabella (che si chiama calendario). I codici lezione sono unici.
All'interno del ciclo while, dopo aver estratto dalla query di cui sopra il codice lezione e la somma relativa, ho messo una semplice query
Codice:
$query1 = ("SELECT titolo FROM calendario WHERE id_lezione = '$lezione'");
che necessariamente mi restituisce un solo record, quindi ho scritto:
Codice:
$tito = mysql_query($query1);
    $riga = mysql_fetch_assoc($tito);
    $titolo = $riga['titolo'];
Poi chiudo il php, aggiungo la riga della tabella da popolare, riapro php, metto l'incremento di $i e chiudo il ciclo while.
Mi aspettavo di avere l'lenco che ottenevo prima con l'aggiunta nell'apposita casella del titolo della lezione.
Invece PRIMA mi visualizza tutti i titoli, POI mi popola la tabella con i due valori di prima (cod lezione e somma utenti)
Come mai? Dove ho sbagliato?
Ecco il codice completo:
Codice:
<table width=100%>
    <tr>
        <td width="20%">Cod. Lezione</td><td width="25%">Titolo Lezione</td><td width="10%">Iscritti</td><td width="45%">&nbsp;</td>
       
    </tr>
    <tr>
        <td colspan="4"><hr></td>
    </tr>


<?

include 'connect.php';

$query = ("SELECT *, sum(postiprenotati) FROM utentiscuola GROUP BY id_lezione ORDER BY sum(postiprenotati), id_lezione");
$lezanno = mysql_query($query);
$numero = mysql_num_rows($lezanno);

//stampo l'anno di riferimento

echo "<p align = 'center'>2016</p>";

$i = 0;
while ($i < $numero) {
    $lezione = mysql_result($lezanno, $i, "id_lezione");
    $somma = mysql_result($lezanno, $i, 'sum(postiprenotati)');

    // Recupero il titolo della lezione

    $query1 = ("SELECT titolo FROM calendario WHERE id_lezione = '$lezione'");
    $tito = mysql_query($query1);
    $riga = mysql_fetch_assoc($tito);
    $titolo = $riga['titolo'];

    ?>

    <tr>
        <td><? echo $lezione; ?></td><? echo $titolo; ?></td><td><? echo $somma; ?></td><td></td>
    </tr>

    <?

    $i++;

}
    ?>

   




</table>
Grazie per l'ulteriore suggerimento
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.046
150
63
PR
www.borgo-italia.it
ciao
prova una cosa del genere (al massimo non funziona)
PHP:
<?php
//....
//intanto potresti dare un alias alla somma
$query = "SELECT id_lezione, sum(postiprenotati) AS totale FROM utentiscuola GROUP BY id_lezione ORDER BY totale, id_lezione";
$ris=mysql_query($query);
//poi semplifica
if(mysql_num_rows($ris)> 0){
    while($riga=mysql_fetch_array($ris)){
        $id_lezione=$riga['id_lezione'];
        $posti_prenotati=$riga['totale'];
        $query1 = "SELECT titolo FROM calendario WHERE id_lezione = $id_lezione";
        //attento immagino che l'id_lezione sia un numero intero: non ci vanno gli apici
        $ris1=mysql_query($query1);
        $riga1=mysql_fetch_array($ris1);
        $titolo=$riga1['titolo'];
        echo "<tr>";
        echo "<td>$titolo</td><td>$posti_prenotati</td>";
        echo "</tr>";
    }
}else{
    echo "non ci sono dati";
}
//.....
?>
inoltre, penso che marino51 si sia dimenticato di dirtelo, abbandona le vecchie istruzioni php mysql obsolete e passa alle nuove mysqli
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.046
150
63
PR
www.borgo-italia.it
ciao
dimenticavo io forse potresti semplificare ulteriormente usando una join(al massimo anche questa non funziona)
PHP:
<?php
//....
//dando i vari alias
$query = "SELECT ut.sum(postiprenotati) AS totale, ca.titolo AS tit 
            FROM utentiscuola AS ut, calendario AS ca
            WHERE ut.id_lezione=ca.id_lezione
            GROUP BY ud.id_lezione ORDER BY totale, ut.id_lezione";
$ris=mysql_query($query);
//poi semplifica
if(mysql_num_rows($ris)> 0){
    while($riga=mysql_fetch_array($ris)){
        $posti_prenotati=$riga['totale'];
        $titolo=$riga1['tit'];
        echo "<tr>";
        echo "<td>$titolo</td><td>$posti_prenotati</td>";
        echo "</tr>";
    }
}else{
    echo "non ci sono dati";
}
//.....
?>
meno chiamate al db si fanno e meno risorse si sprecano
 

gandalf1959

Utente Attivo
21 Nov 2013
208
1
18
Grazie. Adesso devo uscire, poi metto in pratica i suggerimenti.
Una domanda ignorante: mySql a mysqli possono convivere o devo aggiornare tutte le procedure che ho scritto?
 

marino51

Utente Attivo
28 Feb 2013
3.203
207
63
Lombardia
puoi usare,
Codice:
"
SELECT us.id_lezione, sum(us.postiprenotati), cal.titolo
FROM utentiscuola us
LEFT JOIN calendario cal ON us.id_lezione = cal.id_lezione
GROUP BY us.id_lezione
ORDER BY sum(us.postiprenotati), us.id_lezione
";
se sei certissimo che ci sia sempre almeno un titolo in calendario per ogni id_lezione esistente in "utentiscuola", puoi semplificare con
Codice:
"
SELECT us.id_lezione, sum(us.postiprenotati), cal.titolo
FROM utentiscuola us, calendario cal
where us.id_lezione = cal.id_lezione
GROUP BY us.id_lezione
ORDER BY sum(us.postiprenotati), us.id_lezione
";
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.046
150
63
PR
www.borgo-italia.it
ciao
non non possono convivere, però è semplice modificare senza lavorare troppo
le differenze sostanziali sono nella connessione
$con=mysqli_connect("host","user"."pass","nome_db");
poi quella $con va messa nella mysqli_query di select/update/delete
$ris=mysqli_query($conn, "SELECT.....");
nellle altre basta aggiungere una i es. mysql_num_rows diventa mysqli_num_rows
tutto questo per semplificare perchè poi mysqli ha altre caratteristiche (es supporta la programmazione ad oggetti), ma per ora è sufficiente
 

gandalf1959

Utente Attivo
21 Nov 2013
208
1
18
ciao
dimenticavo io forse potresti semplificare ulteriormente usando una join(al massimo anche questa non funziona)
PHP:
<?php
//....
//dando i vari alias
$query = "SELECT ut.sum(postiprenotati) AS totale, ca.titolo AS tit
            FROM utentiscuola AS ut, calendario AS ca
            WHERE ut.id_lezione=ca.id_lezione
            GROUP BY ud.id_lezione ORDER BY totale, ut.id_lezione";
$ris=mysql_query($query);
//poi semplifica
if(mysql_num_rows($ris)> 0){
    while($riga=mysql_fetch_array($ris)){
        $posti_prenotati=$riga['totale'];
        $titolo=$riga1['tit'];
        echo "<tr>";
        echo "<td>$titolo</td><td>$posti_prenotati</td>";
        echo "</tr>";
    }
}else{
    echo "non ci sono dati";
}
//.....
?>
meno chiamate al db si fanno e meno risorse si sprecano

In effetti non funziona... anche correggendo GROUP BY ut... invece di ud :)
Se ho capito bene, la select in questione dice: seleziona dalla tabella utentiscuola, che chiameremo ut e dalla tabella calendario che chiameremo ca, da ut fai la somma di postiprenotati e da ca seleziona il titolo, che chiameremo tit, dove il campo id_lezione di ut e il campo id_lezione di ca sono uguali, poi raggruppa e ordina.
Giusto? Non ho mai utilizzato una query così articolata.
Sembrerebbe tutto corretto, in effetti, ma mi dà poi un errore sulla riga dove c'e'
Codice:
if (mysql_num_rows($ris) > 0) {
che recita:
"Warning: mysql_num_rows() expects parameter 1 to be resource, boolean given in /htdocs/public/www/backoffice/iscritti_per_lezione.php on line 65 Non ci sono dati".
In pratica dovrebbe leggere il campo id_lezione da utentiscuola, trovare la corrispondenza in calendario da cui prende il titolo corrispondente, e poi fare la somma, raggruppare e ordinare, ma non trova nulla.
Scusa la mia ignoranza, ma dov'è l'errore? BTW il tuo snippet di prima funzionava perfettamente, quindi per ora uso quello. La domanda qui è solo per cercare di capire e imparare.
Grazie
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.046
150
63
PR
www.borgo-italia.it
ciao
l'ud è un errore di battitura, comunque è una join implicita (quella di marino è una join esplicita).
intanto usa lo script che funziona, per il secondo prova a mettere un var_dump
PHP:
<?php
//.....
$ris=mysql_query($query);
var_dump($ris);
//poi semplifica
if(mysql_num_rows($ris)> 0){
//......
?>
se da false la query non viene eseguita e quindi è facile che ci sia un errore nella querystringa

dimenticavo: il tuo ragionamento è giusto
 

marino51

Utente Attivo
28 Feb 2013
3.203
207
63
Lombardia
la query di Borgo contiene un errore, modifica così, "sum(ut.postiprenotati)"
ed è simile (identica) alla seconda query del mio ultimo post

ti suggerisco però di non usarla perché, se per qualsiasi motivo, non è presente il titolo nella tabella calendario,
il record non ti viene estratto mentre la "left join" te lo estrae con titolo = null

se vuoi una visuale sulle join, guarda qui
http://www.codeproject.com/KB/database/Visual_SQL_Joins/Visual_SQL_JOINS_orig.jpg
 

gandalf1959

Utente Attivo
21 Nov 2013
208
1
18
mmm non c'e' verso che funzioni con alias e join...
Adesso pero' devo andare avanti con il resto delle cose da aggiungere. Riprenderò più avanti con lo studio...
Intanto grazie
 
Discussioni simili
Autore Titolo Forum Risposte Data
elpirata Query per leggere dati da una tabella mysql e mostrarli a video in base a parametri passati tramite GET PHP 5
A Carattere 'è' in query MySQL PHP 0
M [MySQL] CREARE UN LINK SU UN DETERMINATO CAMPO DI UNA TABELLA RISULTATO DI UNA QUERY SQL MySQL 3
max1974 Query lenta.....Mysql 5.7 MySQL 2
G [MySQL] Connessione DB e query da file batch MySQL 1
V [MySQL] problema query con date su server MySQL 5
P Query Mysql con Join PHP 2
D [MySQL] Tabelle "molti a molti", SELECT con troppe QUERY MySQL 7
G esportare in file .csv risultato di query mysql PHP 5
napuleone [MySQL] commenti in una query MySQL 1
P [MySQL] Query su DB 1 e Insert su DB 2 PHP 11
MarcoGrazia [mysql][mariadb]Raggruppare query in base alla data MySQL 2
G Mysql ( Query) problema interrogazione MySQL 0
danjde [MySQL] Escludere specifico valore dalla query select MySQL 3
C Php/Mysql query JOIN tra tabelle PHP 4
C Php/Mysql query JOIN tra due tabelle PHP 18
P [MYSQL] Query su tabelle con clausola "essenziale" MySQL 10
booklisa MYSQL e PHP Query e sottoquery PHP 3
A Query mssql su mysql con linked server Database 0
I Query DB MYSQL MySQL 0
T query mysql MySQL 3
M Query mysql per selezioni random in categorie mirate PHP 4
M [PHP - MYSQL] Mantenere filtro query in tabelle paginate PHP 3
M Paginazione di risultati query mysql PHP 2
G problema query mysql in php PHP 5
felino [PHP][MySQL] Errore nella query PHP 6
A Form fattura multiriga e query salvataggio mysql PHP 3
N Eseguire una query MySQL dopo 10 secondi PHP 0
A jbutton che esegue una query mysql in netbeans Java 1
IImanuII mysql query random riga PHP 5
G Inserimento loop in una INSERT query in PHP e MySQL PHP 2
L filtri di query [php-mysql] PHP 6
A [RISOLTO]Come generare query dinamica PHP-MYSQL PHP 2
Albertoesse Problemi passaggio valori da un Form ad Una classe con query mysql PHP 12
G Problema con query mysql MySQL 1
B problema query mysql php PHP 1
L PHP: problema con query mysql. PHP 3
M MySql Query ciclo nidificato PHP 3
ivarello Asterisco e query mysql PHP 2
A Indicizzare i risultati di una query Mysql con php PHP 0
F Estrazione da db MySQL con query molto lunga PHP 13
B Aiuto query mysql in php PHP 1
S Autocompletamente con jQuery, PHP e MySQL - Problema con le query PHP 7
M cache query mysql PHP 1
Boscagoo Problema query mySQL MySQL 6
A sintassi query mysql PHP 3
R Quale la funzione mysql query. PHP 3
R Aiutino per query MySql PHP 8
neo996sps [PHP + MySQL + Server Linux] Upload semi riuscito e query non eseguite PHP 2
M Problema query MySQL MySQL 13

Discussioni simili