Newsgroup: it.comp.software.database
Titolo: :mysql: max(ordinazioni)

ragazzi sono un po' demoralizzato, mi inchiodo sempre su semplici query
la tabella "er_piu" ha solo 4 colonne
id | zona | cliente | ordini
------------------------------------
1     N      alex            8
2     N      marco         2
3     S       paolo         1
4     C       luca           10
5     C      mara           9
6     S       ciro            7
zona contiene sempre solo tre record identici "Nord, Centro, Sud"
io vorrei sapere il nome del cliente che ha effettuato la maggior parte
delle ordinazioni per zona,
in pratica solo tre righe
il risultato della query dovrebbe essere
cliente         zona              ordini
---------------------------------------
alex              N                  8
luca              C                 10
ciro               S                  7
usando codesta query
======================
Select  cliente, max(ordini) as ordini
from er_piu
group by zona
=====================
il risultato è sempre errato

non č cosě semplice vero ?
chiederň altrove


Anziché darti solo la query finale ti spiego i passi del ragionamento
che ho fatto per ricavarla. Praticamente faccio una sorta di "join"
della tabella con se stessa.
Con questa query prendi i dati "puliti" dalla tabella:
mysql> select C1.id,C1.cliente,C1.ordini,C1.zona from test_cliente as C1;
+------+---------+--------+------+
| id   | cliente | ordini | zona |
+------+---------+--------+------+
|    1 | alex    |      8 | N    |
|    2 | marco   |      2 | N    |
|    3 | paolo   |      1 | S    |
|    4 | luca    |     10 | C    |
|    5 | mara    |      9 | C    |
|    6 | ciro    |      7 | S    |
+------+---------+--------+------+
Con questa prendi i valori massimi per le varie zone:
mysql> select C2.zona,max(C2.ordini) from test_cliente as C2 group by
C2.zona ;
+------+----------------+
| zona | max(C2.ordini) |
+------+----------------+
| C    |             10 |
| N    |              8 |
| S    |              7 |
+------+----------------+
Con un join tra C1 e C2 ottieni:
mysql> select C1.id,C1.cliente,C1.ordini,C1.zona,C2.zona,max(C2.ordini)
from test_cliente as C1, test_cliente as C2 group by
C1.id,C1.cliente,C2.zona;
+------+---------+--------+------+------+----------------+
| id   | cliente | ordini | zona | zona | max(C2.ordini) |
+------+---------+--------+------+------+----------------+
|    1 | alex    |      8 | N    | C    |             10 |
|    1 | alex    |      8 | N    | N    |              8 |
|    1 | alex    |      8 | N    | S    |              7 |
|    2 | marco   |      2 | N    | C    |             10 |
|    2 | marco   |      2 | N    | N    |              8 |
|    2 | marco   |      2 | N    | S    |              7 |
|    3 | paolo   |      1 | S    | C    |             10 |
|    3 | paolo   |      1 | S    | N    |              8 |
|    3 | paolo   |      1 | S    | S    |              7 |
|    4 | luca    |     10 | C    | C    |             10 |
|    4 | luca    |     10 | C    | N    |              8 |
|    4 | luca    |     10 | C    | S    |              7 |
|    5 | mara    |      9 | C    | C    |             10 |
|    5 | mara    |      9 | C    | N    |              8 |
|    5 | mara    |      9 | C    | S    |              7 |
|    6 | ciro    |      7 | S    | C    |             10 |
|    6 | ciro    |      7 | S    | N    |              8 |
|    6 | ciro    |      7 | S    | S    |              7 |
+------+---------+--------+------+------+----------------+
Che apparentemente sembra non portare a niente, ma filtrando
opportunamente i valori, ossia prendendo solo quelli dove
C1.zona=C2.zona e e C1.ordini=max(C2.ordini) arrivi alla query
che ti interessa:
mysql> select C1.id,C1.cliente,C1.ordini,C1.zona,C2.zona,max(C2.ordini)
from test_cliente as C1, test_cliente as C2 group by
C1.id,C1.cliente,C2.zona having C1.zona=C2.zona and
C1.ordini=max(C2.ordini);
+------+---------+--------+------+------+----------------+
| id   | cliente | ordini | zona | zona | max(C2.ordini) |
+------+---------+--------+------+------+----------------+
|    1 | alex    |      8 | N    | N    |              8 |
|    4 | luca    |     10 | C    | C    |             10 |
|    6 | ciro    |      7 | S    | S    |              7 |
+------+---------+--------+------+------+----------------+
Se vuoi strafare li metti pure in ordine di graduatoria "ordini":
mysql> select C1.id,C1.cliente,C1.ordini,C1.zona,C2.zona,max(C2.ordini)
from test_cliente as C1, test_cliente as C2 group by
C1.id,C1.cliente,C2.zona having C1.zona=C2.zona and
C1.ordini=max(C2.ordini) order by C1.ordini desc;
+------+---------+--------+------+------+----------------+
| id   | cliente | ordini | zona | zona | max(C2.ordini) |
+------+---------+--------+------+------+----------------+
|    4 | luca    |     10 | C    | C    |             10 |
|    1 | alex    |      8 | N    | N    |              8 |
|    6 | ciro    |      7 | S    | S    |              7 |
+------+---------+--------+------+------+----------------+
Per verificare cosa succede a parità di "ordini" tra clienti
ho provato ad inserirne uno nuovo:
mysql> insert into test_cliente values(7,"C","italo",10);
Il risultato della query è il seguente, che giustamente ti mostra
tutti i clienti che nella zona hanno il massimo degli ordini:
mysql> select C1.id,C1.cliente,C1.ordini,C1.zona,C2.zona,max(C2.ordini)
from test_cliente as C1, test_cliente as C2 group by
C1.id,C1.cliente,C2.zona having C1.zona=C2.zona and
C1.ordini=max(C2.ordini) order by C1.ordini desc;
+------+---------+--------+------+------+----------------+
| id   | cliente | ordini | zona | zona | max(C2.ordini) |
+------+---------+--------+------+------+----------------+
|    4 | luca    |     10 | C    | C    |             10 |
|    7 | italo   |     10 | C    | C    |             10 |
|    1 | alex    |      8 | N    | N    |              8 |
|    6 | ciro    |      7 | S    | S    |              7 |
+------+---------+--------+------+------+----------------+
Pant pant pant... eppure all'inizio sembrava semplice...
Bye
gpb