Newsgroup: it.comp.software.database
Titolo: Query SQL: riduzione di un problema complesso [Lungo]

Salve a tutti!
Sono alle prese con una interrogazione a un DB in Access che
inizialmente mi sembrava semplice, ma che in realtà si è dimostrata
complessa.
Comunque, dopo una giornata passata a lurkare internet e i NG con
Google sono giunto alla soluzione. Il problema è che la soluzione mi
pare un po' toppo complessa e volevo qualche consiglio su come
semplificarla.
Innanzitutto il problema.
Ho una tabella (di nome MS) che contiene i seguenti Campi:
CITY: sigla di una città
VALUE: valore della temperatura rilevata in un dato giorno
DATE: giorno della rilevazione
Quello che devo fare è semplicemente selezionare, per ogni città e in
un certo intervallo di tempo (per questo esempio userò tutto il 2005),
il valore massimo della temperatura e la data in cui tale valore è
stato raggiunto.
Sembra facile, ma per ottenere il risultato non solo ci ho tenuto un
sacco di tempo ma ho utilizzato ben quattro query :(
PRIMO PASSO (Query Max2005)
Seleziono per ogni città la temperatura massima raggiunta usando la
funzione max e tramite una join vi associo la data in cui tale valore
è stato raggiunto:
SELECT MS.CITY, MS.DATE, MS.VALUE
FROM MS INNER JOIN [SELECT  MS.CITY, Max(MS.VALUE) AS Max2005
FROM MS
WHERE (((MS.DATE)>=#1/1/2005# And (MetaStock.DATE)<=#12/31/2005#))
GROUP BY MS.CITY
]. AS appo ON (MS.CITY=appo.CITY) AND (appo.Max2005 = MS.VALUE)
WHERE (((MS.DATE)>=#1/1/2005# And (MS.DATE)<=#12/31/2005#))
ORDER BY MS.CITY, MS.DATE DESC;
Fatto questo pensavo di aver finito, ma mi sono reso conto di una cosa:
in molte città la temperatura massima viene raggiunta più volte
nell'arco di un anno. Ho deciso che per ogni città avrei allora preso
il dato relativo alla data più "vecchia".
SECONDO PASSO (Query Max2005D)
Filtro la query precedente selezionando, per ogni città, la data più
vecchia.
SELECT [Max2005].[CITY], Max([Max2005].[DATE]) AS D2005M
FROM Max2005
GROUP BY [Max2005].[CITY];
Ma poichè la funzione max seleziona solo il *valore* massimo e non
l'intera riga, devo procedere con un'altra query.
TERZO PASSO (Query Max2005DV)
Estraggo dalla tabella MS le righe corrispondenti alle date trovate
nella query precedente:
SELECT [MS].[CITY], [MS].[DATE], [MS].[VALUE]
FROM MS RIGHT JOIN Max2005D ON ([Max2005D].[D2005M]=[MS].[DATE]) AND
([Max2005D].[CITY]=[MS].[CITY]);
QUARTO PASSO (Query MAx2005DVN)
Infine, un'ultima complicazione: i dati che devo estrarre devono essere
quelli relativi ad un certo insieme di città, anche se per alcune non
sono presenti dati (ad esempio perchè in quella città nel 2005 non
sono state fatte rilevazioni). Ho quindi creato una tabella chiamata
Nomi con due campi:
CITY: sigla della città (la stessa che compare nella tabella MS)
NOME: il nome per esteso della città
in cui compaiono i nomi di tutte le città che mi interessano.
Ho poi fatto la seguente in cui alle righe della query precedente il
nome per esteso della città.
SELECT [Nomi].[NOME], [Nomi].[CITY], [Max2005DV].[DATE],
[Max2006DV].[VALUE]
FROM Nomi LEFT JOIN Max2005DV ON [Nomi].[CITY]=[Max2006DV].[CITY]
ORDER BY [Nomi].[CITY];
Ok...
Ora faccio un piccolo esempio con dei dati.
Tabella MS
CITY   DATE      VALUE
MI     10/8/2005 30
MI     11/8/2005 31
MI     12/8/2005 31
MI     13/8/2005 29
GE     10/8/2005 33
GE     11/8/2005 32
GE     12/8/2005 30
GE     13/8/2005 32
RM     10/8/2005 29
RM     11/8/2005 29
RM     12/8/2005 32
RM     13/8/2005 32
APPLICO PRIMA QUERY
MI     12/8/2005 31
MI     11/8/2005 31
GE     10/8/2005 33
RM     13/8/2005 32
RM     12/8/2005 32
APPLICO SECONDA QUERY
MI     12/8/2005
GE     10/8/2005
RM     13/8/2005
APPLICO TERZA QUERY
MI     12/8/2005 31
GE     10/8/2005 33
RM     13/8/2005 32
APPLICO QUARTA QUERY
MILANO MI     12/8/2005 31
TORINO TO
GENOVA GE     10/8/2005 33
ROMA   RM     13/8/2005 32
(In questo caso la tabella Nomi conteneva Milano, Torino, Genova e
Roma)
Se qualcuno ha idee su come realizzare quanto esposto in modo più
semplice (o perlomeno su come unire in unica query le quattro query) lo
ascolto volentieri.
Scusate la lunghezza, ma credo che sia un quesito abbastanza
interessante.
Ciao

 Ciao
marc.

 marc.
Ho provato ma si blocca il programma (access). Forse è meglio
utilizzare un RDBMS serio?
Ciao

 Ciao
marc.

 Si blocca? Anche con una tabella di test con pochi dati?
Allora, la mia tabella ha circa 10.000 record e il pc si "blocca"
(cioè access sembra freezato così lo killo), mentre se provo con
circa 1.400 record non si blocca, ma è molto lenta.
Tenendo presente che 10.000 record sono già di test (suppongo che in
versione definitiva potrebbero essere circa 250-300 rilevazioni/anno
per alcune centinaia di località) credo proprio di dover lavorare
sulla velocità (la mia lunghissima query è comunque lenta visto che
impiega qulche secondo); chiunque abbia suggerimenti è ben venuto.
Forse una soluzione è fare una tabella per ogni anno, ma non mi piace
come idea.
Ciao

 Ciao
marc.