Newsgroup: it.comp.www.php
Titolo: Query comp

Devo recuperare i tempi più bassi da più tabelle di concorrenti, dove
ogni tabella è asssociata ad un anno e quindi in futuro aumenteranno.
Essendo una competizione a tappe queste tabelle (concorrenti_2005,
concorrenti_2006, ecc ecc) hanno cinque celle che servono per i tempi di
tappa (t1, t2, t3, t4, t5) e il nome del concorrente.
Mi chiedevo se è possibile usare una unica query per passare tutte le
tabelle ed ottenere il tempi migliori, oppure se c'è e qual'è la
tecnica, megari ricorrendo al PHP.
migliore.
Max
-- 
http://www.maxori.it

 tabelle ed ottenere il tempi migliori, 
Se le tabelle hanno la medesima struttura, con i campi del medesimo 
nome, direi che l'ideale è usare una tranquillissima UNION, tipo:
(SELECT * FROM anno2005)
UNION ALL
(SELECT * FROM anno2006)
UNION ALL
(SELECT * FROM anno2007)
ORDER BY tempomigliore
Così facendo hai l'ordine secondo i tempi migliori globali.
Se vuoi ordinare invece anno per anno, non perdendo il riferimento 
dell'anno, potresti modificare così:
(SELECT *,'2005' FROM anno2005 ORDER BY tempomigliore)
UNION ALL
(SELECT *,'2006' FROM anno2006 ORDER BY tempomigliore)
UNION ALL
(SELECT *,'2007' FROM anno2007 ORDER BY tempomigliore)
Sperando di esserti stato d'aiuto, bye! :-)
--
rob4you
www.outofmind.eu

 
www.outofmind.eu
La query funziona benissimo, grazie.
Ora perň mi č sorto il problema dei parimerito (ce ne sono anche quattro
alla volta!) e sto studiando come fare per avere tutti gli aitleti che
hanno lo stesso record.
Con MIN(tempo1) teoricamente dovrei recuperare proprio quelli, ma se uso
GROUP BY mi dice che c'č un errore nella struttura della query, sia che
lo usi al di fuori delle UNION sia all'interno.
Max
-- 
http://www.maxori.it

 hanno lo stesso record.
Vuoi ottenere SOLTANTO gli altleti che hanno realizzato lo stesso 
tempo?
Ma vuoi ottenere il tempo migliore, o comunque il numero di atleti che 
hanno realizzato i vari tempi?
Magari fai un esempio di come vorresti apparisse il risultato, così 
vediamo di trovare una soluzione. "forse" non dovrebbe essere troppo 
proibitiva. :-)
--
rob4you

 rob4you
Mi rendo conto...
In pratica:
Best time T1: Carlo Rossi, 02:01:33 (2005)
Best Time T2: Paolo Ferrari, 01:03:45 (2007)
Best Time T3: Carlo Rossi 03:44:02 (2006)
Best Time T4: Pippo Paperino, Topo Topolino 01:33:25 (2005)
Best Time T5: Carlo Rossi 00:54:35 (2005, 2007)
Non č per niente semplice, mi sembra.
Max
-- 
http://www.maxori.it

 Best Time T5: Carlo Rossi 00:54:35 (2005, 2007)
Ahh, cioè in pratica, dal momento che hai 5 campi (t1,2,3,4,5) per ogni 
tabella, più un altro campo "nome_concorrente", e hai 1 tabella per 
ogni anno, tu vorresti ottenere un ordinamento secondo cui lo stesso 
tempo potrebbe essere stato ottenuto da due concorrenti (come 
nell'esempio che tu hai riportato ciò accade per T4), o anche dallo 
stesso concorrente in due anni diversi (come riga T5), o addirittura da 
due concorrenti diversi in due anni diversi (anche se questo caso non 
appar nell'esempio che tu hai riportato).
Ora vedo di fare un po' di prove, non si sa mai. :-)
--
rob4you

 rob4you
Si, infatti questa č la query piů complessa che mi sia mai capitata...
Un bel casino... e grazie per l'aiuto.
Se ne veniamo a capo e passo dalle tue parti ti offro la pizza...
Max
-- 
http://www.maxori.it

> Se ne veniamo a capo e passo dalle tue parti ti offro la pizza...
Preparati a offire la pizza. :-)
Sto risolvendo..ho quasi fatto....faccio gli ultimi ritocchini. ;-)
--
rob4you

 wrote:

Ahi ahi ahi, io ho già fatto...
Max
-- 
http://www.maxori.it

 Ahi ahi ahi, io ho già fatto...
http://www.100kmdelsahara.com/classifica.php
Max
-- 
http://www.maxori.it

 
http://www.100kmdelsahara.com/classifica.php
E manco il tempo di finire di pranzare in santa pace! :-)
Se hai risolto complimenti allora! A proposito, carino il tuo progetto.
ps: comunque, se ti può interessare, io ero riuscito a ottenere la 
tabella di esempio che avevi postato qui, utilizzando un paio di viste 
e una sola query di selezione.
--
rob4you

 e una sola query di selezione.
Spara, spara, la pizza è sempre lì...
A proposito, di dove sei? Io di Modena.
Max
-- 
http://www.maxori.it

 A proposito, di dove sei? Io di Modena.
Bari. Lontanucci...ma non si sa mai. :-)
Allora, ora ti posto la mia soluzione, te ne posto prima una più 
semplice poi una più complessa (e completa).
Come partenza abbiamo le varie tabelle che tu hai detto (chiamamole 
anno2005,anno2006,anno2007).
Ognuna di queste tabelle e così fatta (per semplicità e per far le 
prove non ho messo tutte e cinque le tappe, ma solo le prime due; non 
ho messo nemmeno una primary key, vabbé, fa niente :-) ):
CREATE TABLE `anno2007` (
  `nome` varchar(20) NOT NULL,
  `T1` time NOT NULL,
  `T2` time NOT NULL
)
Ho riempito le varie tabelle con dei nomi e tempi.
Ciò premesso, ho pensato a due possibili soluzioni.
- Prima soluzione:
Ho creato una vista per ogni tappa, quindi in questo caso ci vorrebbero 
due viste (nel caso completo ci vorrebbero 5 viste).
Ecco ad esempio la vista per la tappa numero 1:
CREATE VIEW `vistaT1` AS
(SELECT `nome`, `T1`, '2005' AS `anno` from `anno2005`)
UNION
(SELECT `nome`, `T1`, '2006' AS `anno` from `anno2006`)
UNION
(SELECT `nome`, `T1`, '2007' AS `anno` from `anno2007`)
order by `T1`;
A questo punto per ottenere una riga del tipo:
T1 | Mario Rossi,Giuseppe Verdi | 01:00:55 | 2005,2006
Si può scrivere:
(SELECT 'T1' as tappa,
     GROUP_CONCAT(DISTINCT nome ORDER BY nome) as nomi,
     MIN(T1),
     GROUP_CONCAT(anno ORDER BY anno) as anni
 FROM vistaT1 GROUP BY T1 LIMIT 1);
Se vuoi visualizzare contemporaneamente le varie tappe, tipo:
T1 | Mario Rossi,Giuseppe Verdi | 01:00:55 | 2005,2006
T2 | Carlo Bianchi | 02:30:40 | 2007
Basta fare una UNION tra `vistaT1` e `vistaT2` con la query che ho 
scritto sopra:
(SELECT 'T1' as tappa,
     GROUP_CONCAT(DISTINCT nome ORDER BY nome) as nomi,
     MIN(T1),
     GROUP_CONCAT(anno ORDER BY anno) as anni
 FROM vistaT1 GROUP BY T1 LIMIT 1);
UNION
(SELECT 'T2' as tappa,
     GROUP_CONCAT(DISTINCT nome ORDER BY nome) as nomi,
     MIN(T2),
     GROUP_CONCAT(anno ORDER BY anno) as anni
 FROM vistaT2 GROUP BY T2 LIMIT 1);
Questa è dunque la prima soluzione, che richiede appunto una vista per 
ciascuna tappa (nel tuo caso dovrebbero esserci quindi 5 viste).
Se invece vuoi una sola vista, ecco cosa di seguito la seconda 
soluzione.
- Seconda soluzione:
La vista per questa soluzione appare così:
CREATE VIEW `vista1` AS
(SELECT `nome`,
     'T1' AS `tappa`,
     `T1` AS `tempo`,
     '2005' AS `anno`
 FROM `anno2005`)
UNION ALL
(SELECT `nome`,
     'T1' AS `tappa`,
     `T1` AS `tempo`,
     '2006' AS `anno`
 FROM `anno2006`)
UNION ALL
(SELECT `nome`,
     'T1' AS `tappa`,
     `T1` AS `tempo`,
     '2007' AS `anno`
 FROM `anno2007`)
UNION ALL
(SELECT `nome`,
     'T2' AS `tappa`,
     `T2` AS `tempo`,
     '2005' AS `anno`
 FROM `anno2005`)
UNION ALL
(SELECT `nome`,
     'T2' AS `tappa`,
     `T2` AS `tempo`,
     '2006' AS `anno`
 FROM `anno2006`)
UNION ALL
(SELECT `nome`,
     'T2' AS `tappa`,
     `T2` AS `tempo`,
     '2007' AS `anno`
 FROM `anno2007`)
ORDER BY `tappa`,`tempo`,`anno`;
Fatto ciò, ecco la query per ottenere un risultato del tipo:
T1 | Mario Rossi,Giuseppe Verdi | 01:00:55 | 2005,2006
T2 | Carlo Bianchi | 02:30:40 | 2007
(SELECT GROUP_CONCAT(DISTINCT nome ORDER BY nome) as nomi,
     tappa,
     MIN(tempo) as min,
     GROUP_CONCAT(anno ORDER BY anno) as anni
 FROM vista1 WHERE tappa='T1' GROUP BY tempo ORDER BY tempo LIMIT 1)
UNION ALL
(SELECT GROUP_CONCAT(DISTINCT nome ORDER BY nome) nomi,
     tappa,
     MIN(tempo) as min,
     GROUP_CONCAT(anno ORDER BY anno) as anni
 FROM vista1 WHERE tappa='T2' GROUP BY tempo ORDER BY tempo LIMIT 1);
Spero che sia arrivato a leggere fino a questo punto. :-)
Se così non fosse...don't worryyy......a volte si rincretinisce con le 
cose scritte dagli altri.
Probabilmente le varie cose possono anche essere fatte meglio, però 
questa è stata la prima cosa che mi è venuta in mente.
In realtà può sembrare difficile a leggerla, ma in realtà la struttura 
è semplicissima, ed è fatta solo da blocchi simili.
E poi....credimi, questa è una delle mie primissime query "semi-serie" 
in SQL, quindi se ci sono arrivato io così, esisteranno quasi 
sicuramente dei metodi più efficienti. :-)
--
rob4you