|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Apr 2004
Città: La regione del Triplete
Messaggi: 5730
|
[SQL] Una query mySQL che non funge
Ho queste due relazioni:
musei(ID_museo, nome, città, numero_sale, nazione) quadri(ID_quadro, titolo, periodo, autore, id_museo) in cui ho evidenziato in grassetto la chiave primaria e in corsivo quella esterna. Ho una query da risolvere che dice di trovare quali musei hanno un numero di quadri superiore alla media complessiva per quella nazione. Questo è il mio codice che coincide con quello della soluzione, ma non funziona. Codice:
SELECT nome,COUNT(*) as tot FROM Musei M INNER JOIN Quadri Q ON Q.id_museo=M.ID_museo GROUP BY M.ID_museo HAVING tot > ( (SELECT COUNT(*) FROM Quadri WHERE Quadri.id_museo=M.ID_museo) / (SELECT COUNT(*) FROM Quadri WHERE Quadri.id_museo=M.ID_museo GROUP BY M.nazione) ) Sapreste indicarmi anche una strategia per risolvere le query annidate molto complesse? Per quanto riguarda l'uso delle variabili mi potreste chiarire quando è opportuno inserirle nei casi di query annidate? Grazie.
__________________
Trattative felicemente concluse con domienico120, xbax88 ed engiel, ottimi e seri utenti. Ultima modifica di zanardi84 : 17-08-2012 alle 16:58. |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Jul 2008
Messaggi: 485
|
Nelle due relazioni che hai riportato non esiste alcun attributo nazione, quindi è normale che tu ottenga quell'errore. Se non ci sono altri problemi (non ho provato la query) ti basta sostituire nazione con città, l'unico attributo che gli si avvicina concettualmente.
Forse si tratta di un refuso nella traccia/tabella o, in alternativa, dovrebbe esistere una terza relazione, o un semplice attributo aggiuntivo, che associa ciascuna città ad una nazione |
![]() |
![]() |
![]() |
#3 | |
Senior Member
Iscritto dal: Nov 2004
Messaggi: 1747
|
Quote:
Scusa ma non l'hai chiamato "nazioni" nella tabella? Nella query usi "M.nazione".
__________________
Esistono 10 tipi di persone al mondo: quelli che capiscono il codice binario e quelli che non lo capiscono |
|
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Apr 2004
Città: La regione del Triplete
Messaggi: 5730
|
Chiedo scusa, è nazione, non nazioni. Correggo anche nel thread iniziale.
__________________
Trattative felicemente concluse con domienico120, xbax88 ed engiel, ottimi e seri utenti. |
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: Nov 2004
Città: Padova
Messaggi: 2342
|
Quote:
Fai un select del conteggio dei quadri raggruppati secondo un attributo che appartiene a un'altra tabella... secondo me l'errore sta in questo... prova a controllare. ps: per quanto riguarda lo stile, ti consiglio: tutto in minuscolo (ID_museo -> id_museo), e il nome dei campi del tipo "id_xxxx" usarli solo per gli id usati come chiavi primarie. Per esempio nella tabella quadri, avrei messo "museo" e non "id_museo", in quanto quell'attributo è si l'id del museo, ma rappresenta l'intero museo.
__________________
CPU Ryzen 2600 @ 3,95Ghz + Bequiet Dark Rock TF / MB Asus X470-F Gaming / RAM 2x8GB DDR4 G.Skill FlareX 3200 CL14 / VGA Sapphire RX 7900 XT Nitro+ @ 3200Mhz / SSD Samsung 970 Pro 512GB + Sandisk 240GB Plus + Sandisk 960GB Ultra II PSU Seasonic Platinum P-660 / Headset Kingston HyperX Flight Ultima modifica di demos88 : 17-08-2012 alle 17:22. |
|
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3691
|
Quando scrivi
Having tot> (bla bla) oppure anche quando scrivi Where qualcosa > (bla bla) dove quel blabla vuoi che sia una sottoquery, allora questa sottoquery deve restituire uno scalare. Ovvero nel tuo caso devi far restituire la media dei quadri della nazione del record che stai processando sulla riga master La Join non la devi fare per museo, ma per nazione. E ho idea che non ci sara' nessuna GROUP BY
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. Ultima modifica di gugoXX : 18-08-2012 alle 12:41. |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Nov 2004
Città: Padova
Messaggi: 2342
|
supponendo che le relazioni siano (ho apportato qualche modifica):
Codice:
musei(id_museo, nome, città, numero_sale, nazione) quadri(id_quadro, titolo, periodo, autore, museo) Codice:
SELECT y.museo, x.nazione, x.medianaz, y.nqm FROM ( SELECT a.nazione, nqn, nmn, nqn/nmn AS medianaz FROM ( SELECT nazione, COUNT(*) AS nqn FROM musei JOIN quadri ON id_museo = museo GROUP BY nazione ) a JOIN ( SELECT nazione, COUNT(*) AS nmn FROM musei GROUP BY nazione) b ON a.nazione = b.nazione ) x JOIN ( SELECT nazione, museo, COUNT(*) AS nqm FROM musei JOIN quadri ON id_museo = museo GROUP BY museo ) y ON x.nazione = y.nazione WHERE y.nqm > x.medianaz ![]() nqn = numero quadri nazione nmn = numero musei nazione nqm = numero quadri museo medianaz = media nazionale di quadri per museo la relazione a conta i quadri per nazione, la relazione b conta il numero di musei per nazione. x è il join di a con b e l'attributo x.medianaz è il rapporto nqn/nmn. x è joinato a y che conta il numero di quadri per ogni museo, dal join x*y tengo solo le tuple in cui nqm > medianaz. Provato in locale e mi pare che funzioni ![]() ps: non escludo l'esistenza di soluzioni più eleganti con l'uso di funzioni SQL, questa mi è venuta in mente così... e mi sa che esiste più di un modo di scrivere la stessa query che ho scritto sopra.
__________________
CPU Ryzen 2600 @ 3,95Ghz + Bequiet Dark Rock TF / MB Asus X470-F Gaming / RAM 2x8GB DDR4 G.Skill FlareX 3200 CL14 / VGA Sapphire RX 7900 XT Nitro+ @ 3200Mhz / SSD Samsung 970 Pro 512GB + Sandisk 240GB Plus + Sandisk 960GB Ultra II PSU Seasonic Platinum P-660 / Headset Kingston HyperX Flight Ultima modifica di demos88 : 18-08-2012 alle 15:41. |
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Apr 2004
Città: La regione del Triplete
Messaggi: 5730
|
Quando dovete formulare una query quali sono i ragionamenti che fate?
Cosa vi fa optare per una subquery? Quando usare il self join? Alla fine conosco la sintassi e le definizioni degli operatori, ma non riesco a formulare efficaci interrogazioni.
__________________
Trattative felicemente concluse con domienico120, xbax88 ed engiel, ottimi e seri utenti. |
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Nov 2004
Città: Padova
Messaggi: 2342
|
Quote:
Non c'e' una regola che ti dice quando usare una sottoquery o un selfjoin, lì sul momento vedi che ti serve... e spesso esistono più strade per raggiungere lo stesso risultato
__________________
CPU Ryzen 2600 @ 3,95Ghz + Bequiet Dark Rock TF / MB Asus X470-F Gaming / RAM 2x8GB DDR4 G.Skill FlareX 3200 CL14 / VGA Sapphire RX 7900 XT Nitro+ @ 3200Mhz / SSD Samsung 970 Pro 512GB + Sandisk 240GB Plus + Sandisk 960GB Ultra II PSU Seasonic Platinum P-660 / Headset Kingston HyperX Flight |
|
![]() |
![]() |
![]() |
#10 |
Member
Iscritto dal: Nov 2007
Messaggi: 143
|
Ciao, di seguito trovi una delle tante soluzioni possibili.
Codice:
declare @t table ( IdMuseo int, Nazione varchar(50), NumQuadMuseo int ) declare @t2 table ( Nazione varchar(50), AVGQuadNazione decimal(18,2) ) insert @t ( IdMuseo , Nazione , NumQuadMuseo ) select M.ID_museo, M.nazione, COUNT(*) as QuadriMuseo from @musei M inner join @quadri Q on M.ID_museo = Q.id_museo group by M.ID_museo, M.nazione insert into @t2 ( Nazione, AVGQuadNazione ) select T.nazione, AVG(convert(decimal(18,2), T.NumQuadMuseo)) from @t T group by T.nazione select * from @t T where T.NumQuadMuseo >= ( select T2.AVGQuadNazione from @t2 T2 where T2.nazione = T.nazione ) order by T.IdMuseo Ciao, Yuri. |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 19:14.