Autore |
Discussione  |
|
Nazgul
Utente giovane

Regione: Puglia
Prov.: Bari
Città: Bari
|
Inserito il - 25/08/2009 : 03:47:47
|
Ciao a tutti, stavo facendo delle prove dopo aver finito tutti gli esercizi, giusto per togliermi dei dubbi e andare in scioltezza all'appello ed ho trovato un bug che mi ha messo abbastanza sotto stress.
Questo è un DB della Lisi su cui poi si fanno le solite query: http://pastebin.com/f50d77dcf
Se provate a lanciare la query:
select CodCliente, Cognome, Nome from Ordini NATURAL JOIN Clienti where Data='2002-09-05';
questa qui funzionerà senza problemi,
se invece provate a lanciare la query:
select * from Rappresentanti NATURAL JOIN Clienti;
questa darà come risultato un insieme vuoto. La cosa è molto strana, perché l'attributo di Join col nome uguale c'è ed è CodRappr. Il NATURAL JOIN è utile quando, ad es., si creano delle viste per non avere il messaggio "colonna duplicata" o qualcosa del genere.
Se però c'è un bug allora sono guai, perché all'esame non voglio avere intoppi e a fortuna non sto messo bene... Potete controllare? La versione che sto usando è la 5.0.84-community-nt
|
Modificato da - Nazgul in Data 25/08/2009 03:51:20
|
|
logan
Nuovo Utente
|
Inserito il - 25/08/2009 : 10:39:08
|
Scusa ma nn usare il natural join.. usa il prodotto cartesiamo o il join normale e nella select invece di mettere asterisco seleziona i campi pe rnn avere colonne duplicate |
 |
|
Nazgul
Utente giovane

Regione: Puglia
Prov.: Bari
Città: Bari
|
Inserito il - 25/08/2009 : 12:07:25
|
Citazione: Messaggio inserito da logan
Scusa ma nn usare il natural join.. usa il prodotto cartesiamo o il join normale e nella select invece di mettere asterisco seleziona i campi pe rnn avere colonne duplicate
Questo sarebbe un workaround, non la soluzione al problema. A me serve il Natural Join perché uno meno scrive meno errori rischia di fare. Per fare il JOIN senza colonne duplicate devo elencare nella SELECT tutti gli attributi di R1 e tutti gli attributi di R2 delle 2 relazioni (nel caso in cui debba fare 2 query ad es. sulla stessa vista). Se faccio: create view pippo as select * from r1 as r, r2 as s where r.joinattr = s.joinattr;
Il compilatore mi mena le mani perché ci sono 2 colonne che si chiamano joinattr. Quindi, se le 2 relazioni hanno insieme 10 attributi, li devo scrivere tutti e 10. |
Modificato da - Nazgul in data 25/08/2009 12:07:45 |
 |
|
Nazgul
Utente giovane

Regione: Puglia
Prov.: Bari
Città: Bari
|
Inserito il - 25/08/2009 : 12:29:32
|
Aaaah, queste sono soddisfazioni. Sono andato sul canale del Mysql e abbiamo appurato che il NATURAL JOIN in Mysql non funziona come nella teoria dei DB relazionali.
Praticamente, il NATURAL JOIN ha bisogno che tutti gli attributi delle due relazioni siano uguali.
Per poter applicare il NATURAL JOIN su di un "insieme ristretto" di attributi bisogna usare la condizione ON. |
Modificato da - Nazgul in data 25/08/2009 12:30:16 |
 |
|
Nazgul
Utente giovane

Regione: Puglia
Prov.: Bari
Città: Bari
|
Inserito il - 25/08/2009 : 13:11:24
|
Citazione: Messaggio inserito da Nazgul
Aaaah, queste sono soddisfazioni. Sono andato sul canale del Mysql e abbiamo appurato che il NATURAL JOIN in Mysql non funziona come nella teoria dei DB relazionali.
Praticamente, il NATURAL JOIN ha bisogno che tutti gli attributi delle due relazioni siano uguali.
Per poter applicare il NATURAL JOIN su di un "insieme ristretto" di attributi bisogna usare la condizione ON.
Come non detto, il NATURAL JOIN opera su tabelle che hanno gli attributi che si chiamano tutti alla stessa maniera, ma... non c'è verso di applicarlo su tabelle con attr che non sono tutti uguali. Almeno... così ho capito. Ergo bisogna fare select r1.attr,r2.attr,... addio per fare il join di 3 tabelle se ne va mezz'ora se lo voglio usare in una view ad es. |
Modificato da - Nazgul in data 25/08/2009 13:11:47 |
 |
|
Nazgul
Utente giovane

Regione: Puglia
Prov.: Bari
Città: Bari
|
Inserito il - 25/08/2009 : 13:24:35
|
Citazione: Messaggio inserito da Nazgul
Citazione: Messaggio inserito da Nazgul
Aaaah, queste sono soddisfazioni. Sono andato sul canale del Mysql e abbiamo appurato che il NATURAL JOIN in Mysql non funziona come nella teoria dei DB relazionali.
Praticamente, il NATURAL JOIN ha bisogno che tutti gli attributi delle due relazioni siano uguali.
Per poter applicare il NATURAL JOIN su di un "insieme ristretto" di attributi bisogna usare la condizione ON.
Come non detto, il NATURAL JOIN opera su tabelle che hanno gli attributi che si chiamano tutti alla stessa maniera, ma... non c'è verso di applicarlo su tabelle con attr che non sono tutti uguali. Almeno... così ho capito. Ergo bisogna fare select r1.attr,r2.attr,... addio per fare il join di 3 tabelle se ne va mezz'ora se lo voglio usare in una view ad es.
Questa query pare fare quello che voglio io: select * from r1 JOIN r2 USING (lista_attributi);
|
 |
|
Nazgul
Utente giovane

Regione: Puglia
Prov.: Bari
Città: Bari
|
Inserito il - 25/08/2009 : 13:39:15
|
Citazione: Messaggio inserito da Nazgul
Citazione: Messaggio inserito da Nazgul
Citazione: Messaggio inserito da Nazgul
Aaaah, queste sono soddisfazioni. Sono andato sul canale del Mysql e abbiamo appurato che il NATURAL JOIN in Mysql non funziona come nella teoria dei DB relazionali.
Praticamente, il NATURAL JOIN ha bisogno che tutti gli attributi delle due relazioni siano uguali.
Per poter applicare il NATURAL JOIN su di un "insieme ristretto" di attributi bisogna usare la condizione ON.
Come non detto, il NATURAL JOIN opera su tabelle che hanno gli attributi che si chiamano tutti alla stessa maniera, ma... non c'è verso di applicarlo su tabelle con attr che non sono tutti uguali. Almeno... così ho capito. Ergo bisogna fare select r1.attr,r2.attr,... addio per fare il join di 3 tabelle se ne va mezz'ora se lo voglio usare in una view ad es.
Questa query pare fare quello che voglio io: select * from r1 JOIN r2 USING (lista_attributi);
Esempio
Nell'appello del 09-06-09
6) Creare una vista Filiali_PocketBooks che elenchi i nomi delle filiali che vendono libri pubblicati dall’editore denominato Pocket Books, indicando anche i titoli di tali libri. 7) Per ciascuna filiale che vende libri pubblicati dall’editore denominato Pocket Books, trovare il numero di copie disponibili - presso la filiale - di ciascuno di questi libri (N.B.: lo svolgimento deve riutilizzare la vista Filiali_PocketBooks).
# Esercizio 6) drop view if exists Filiali_PocketBooks; create view Filiali_PocketBooks as SELECT * FROM (Editori JOIN Libri USING (Codice_editore)) JOIN (Scorte JOIN Filiali Using (Nro_filiale)) USING (Codice_libro) WHERE Nome_editore='Pocket Books';
select Distinct Nome_filiale from Filiali_PocketBooks;
# Esercizio 7)
SELECT Titolo_libro, Nome_filiale, nro_copie_disponibili FROM Filiali_PocketBooks ORDER BY (Titolo_libro);
Immaginate il punto 6 altrimenti.  Dovevo prima creare una tabella temporanea dove mettere i dati della tabella di join con un select attr1,attr2, che non finiva + Poi creare la vista. Invece così bello, semplice, 1 comando, 1 sola riga, finito... :D
Questa volta l'ho testato prima di postare e funziona. |
Modificato da - Nazgul in data 25/08/2009 13:40:02 |
 |
|
logan
Nuovo Utente
|
Inserito il - 25/08/2009 : 17:14:08
|
# Esercizio 6)
drop view if exists Filiali_PocketBooks;
create view Filiali_PocketBooks (nomi_filiali,titolo_libri) as (select f.nome_filiale,l.titolo_libro from filiali f,scorte s, libri l,editori e where f.nro_filiale=s.nro_filiale and s.codice_libro=l.codice_libro and l.codice_editore=e.codice_editore and e.nome_editore='Pocket Books' order by f.nome_filiale);
ecco come ho fatto il punto 6 |
 |
|
Nazgul
Utente giovane

Regione: Puglia
Prov.: Bari
Città: Bari
|
Inserito il - 29/08/2009 : 00:22:28
|
Rifatto, più o meno come hai fatto tu. L'importante e non usare "SELECT *", in caso di JOIN nella view soprattutto, per non avere il problema degli attributi che si chiamano alla stessa maniera. Tutto il casino è nato vedendo questo esempio:
Citazione:
[6 punti] Elencare, fido per fido, il numero dei clienti del rappresentante 03 con quel fido limitandosi a considerare i fidi attribuiti a più di un solo cliente. 6) [6 punti] Trovare codice, cognome e nome di ogni cliente con saldo inferiore a 1000 e fido superiore al saldo. Risolvere mediante definizione di una vista (denominata PiccoliClienti) che seleziona i clienti con saldo inferiore a 1000 e successiva interrogazione su tale vista.
# Esercizio 6)
CREATE VIEW PiccoliClienti AS
SELECT *
FROM Clienti
WHERE Fido<=1000;
SELECT CodCliente, Cognome, Nome
FROM PiccoliClienti
WHERE Saldo>Fido;
Qui non ci sono JOIN e la Prof.sa ha preferito semplificarsi le cose con select *, evitando di fare il JOIN per la seconda parte dell'esercizio.
In teoria questa query andava fatta così, rispetto alla traccia:
#ESERCIZIO 6
DROP VIEW IF EXISTS PiccoliClienti;
CREATE VIEW PiccoliClienti AS
SELECT CodCLiente, Cognome, Nome
FROM Clienti
WHERE Saldo < 1000;
SELECT p.CodCLiente, p.Cognome, p.Nome
FROM PiccoliClienti p JOIN Clienti c
ON p.CodCliente = c.CodCliente
WHERE Fido > saldo;
In questo modo la traccia viene rispettata alla lettera, si evita una vista calderone che a quel punto perde il suo perché e si evita il problema degli attributi duplicati che sono quelli di JOIN nel caso in cui nella vista ci sia un JOIN.
Quindi i punti 6 ed il punto 7 del 09-06-09 diventano:
# Esercizio 6)
drop view if exists Filiali_PocketBooks;
create view Filiali_PocketBooks as
select Nome_filiale, Titolo_libro, f.Nro_filiale
from Filiali as f JOIN Scorte as s JOIN Libri as l JOIN Editori as e
ON f.Nro_filiale = s.Nro_filiale AND s.Codice_libro = l.Codice_libro AND l.Codice_editore = e.Codice_editore
where Nome_editore = 'Pocket Books'
GROUP BY Nome_Filiale, Titolo_libro;
# Esercizio 7)
SELECT fpb.Nome_Filiale, fpb.Titolo_libro, Nro_copie_disponibili
FROM Filiali f JOIN Scorte s JOIN Libri l JOIN Filiali_PocketBooks fpb
ON f.Nro_filiale=s.Nro_filiale AND s.Codice_libro = l.Codice_libro
AND fpb.Nome_filiale = f.Nome_filiale AND fpb.Titolo_libro = l.Titolo_libro
GROUP BY Nome_filiale, Titolo_libro;
Nome_filiale e Titolo_libro sono praticamente chiave primaria della vista e quindi bisogna metterli tutti e 2 tra gli attributi di JOIN da quello che ho capito.
Mi sono rifatto tutti gli esercizi di conseguenza e mo sto più o meno tranquillo. Gli errori che faccio spesso sono dimenticarmi l'AS alla fine della riga create view e poi a volte dopo "drop view if exists pippo;" faccio "create view if not exists pippo as" invece di "create view pippo as" e basta.
Una nota marginale: mi pare di aver capito che la prof preferisca il GROUP BY all'ORDER BY perché l'ORDER BY può ordinare solo 1 colonna, mentre il GROUP BY più di una. Ma è una cosa di poco conto.
Ci si vede lunedì.
|
Modificato da - Nazgul in data 29/08/2009 00:35:39 |
 |
|
airbag
utente salvato da un
  

Città: manchester
|
Inserito il - 29/08/2009 : 01:49:49
|
group by non ordina niente, partiziona l'insieme di tuple e su ogni insieme vengono poi eseguiti gli altri predicati
|
<>Can't you see them? Can't you see them? roots can't hold them Bugs console them<> <big><big><big><i><font color="#000033">since yourheadisshacking inthat yourarmsareshacking inthat yourfeetareshacking cause theEarthisshackin'</font></i></big></big></big> |
 |
|
Nazgul
Utente giovane

Regione: Puglia
Prov.: Bari
Città: Bari
|
Inserito il - 29/08/2009 : 11:54:07
|
Citazione: Messaggio inserito da airbag
group by non ordina niente, partiziona l'insieme di tuple e su ogni insieme vengono poi eseguiti gli altri predicati
Siamo d'accordo, ma il risultato finale è quello. http://www.daniweb.com/forums/thread32342.html http://www.sql-tutorial.com/sql-order-by-sql-tutorial/
Su queste risorse ho trovato dei buoni esempi. Cmq, avendo effettuato le query, posso dire che o usando GROUP BY (opportunamente) o usando ORDER BY il risultato della query, per lo meno quelle degli esercizi, non cambia. Che poi operino in maniera diversa siamo d'accordo. Ma anche JOIN, IN, EXISTS operano in maniera diversa ed hanno sintassi diversa, però usati nel modo opportuno producono lo stesso risultato. Poi, dopo essermi andato a vedere quegli esempi, di nuovo, non capisco la perplessità iniziale della Prof.sa nel vedere l'ORDER BY in un esercizio che Le ho fatto vedere (dove non c'erano funzioni aggregate). Non mi ha detto che era errato, però anche chiedendo ad un altro Prof. che insegna Basi di dati, dopo avergli fatto vedere la stessa query, mi ha detto che l'ORDER BY era uno stratagemma che avevo usato io per ottenere il risultato voluto, ma che avrei dovuto usare il group by. La query non contiene funzioni aggregate, ripeto. A voi l'ardua sentenza. :D
Cmq, pensandoci bene, una cosa su cui fare attenzione quando si usa il group by c'è. Ovvero, l'ORDER BY ordina e basta i risultati in base agli attributi che noi esplicitiamo. Il group by invece se ad esempio scriviamo GROUP BY Cognome ed in una tupla ci sono 2 persone con cognome uguale, esso scarta la seconda tupla dal risultato. Idem se facciamo GROUP BY e ci sono 2 persone con Cognome e nome uguale. Quindi, bisogna mettere, come specificato in una delle due risorse, tutti gli attributi che compaiono nella select, accanto alla condizione group by, per evitare che delle tuple vengano eliminate. Questo però non mi ha mai dato problemi, perché dopo aver visto degli esempi ho sempre messo tutti gli attributi della select accanto alla condizione group by.
|
Modificato da - Nazgul in data 29/08/2009 12:02:31 |
 |
|
airbag
utente salvato da un
  

Città: manchester
|
Inserito il - 29/08/2009 : 12:02:12
|
non hai capito neanche i link che hai postato (il secondo poi spiega solo l'order by), rileggiti il primo sono due cose totalmente diverse, se per una volta ti capita che per una data istanza di un db quelle due query diano un output uguale sappi che non è la norma |
<>Can't you see them? Can't you see them? roots can't hold them Bugs console them<> <big><big><big><i><font color="#000033">since yourheadisshacking inthat yourarmsareshacking inthat yourfeetareshacking cause theEarthisshackin'</font></i></big></big></big> |
 |
|
Nazgul
Utente giovane

Regione: Puglia
Prov.: Bari
Città: Bari
|
Inserito il - 29/08/2009 : 12:11:51
|
Parlando di esempi concreti:
5) [punti 6] Per ciascun editore elencare i titoli di libri da esso pubblicati indicandone anche il tipo.
--------------
SELECT Nome_editore, Titolo_libro, Tipo_libro
FROM Libri as l JOIN Editori as e ON e.Codice_editore = l.Codice_editore
GROUP BY Nome_editore, Titolo_libro, Tipo_libro
--------------
+-----------------+----------------------------+------------+
| Nome_editore | Titolo_libro | Tipo_libro |
+-----------------+----------------------------+------------+
| Bantam Books | Amerika | NAR |
| Bantam Books | Castle | NAR |
| Bantam Books | Death on the Nile | MYS |
| Bantam Books | Ghost from the Grand Banks | SFI |
| Bantam Books | Hymns to the Night | POE |
| Bantam Books | Night Probe | SUS |
| Bantam Books | Shyness | PSY |
| Bantam Books | Stranger | NAR |
| Bantam Books | Vixen 07 | SUS |
| Bantam Books | Vortex | SUS |
| Best and Furrow | A Guide to SQL | COM |
| Best and Furrow | Database Systems | COM |
| Best and Furrow | dBase Programming | COM |
| Best and Furrow | DOS Essentials | COM |
| Pocket Books | Dunwich Horror and Others | HOR |
| Pocket Books | Evil Under the Sun | MYS |
| Pocket Books | First Among Equals | NAR |
| Pocket Books | Higher Creativity | PSY |
| Pocket Books | Kane and Abel | NAR |
| Pocket Books | Knockdown | MYS |
| Pocket Books | Marcel Duchamp | ART |
| Pocket Books | Prints of the 20th Century | ART |
| Pocket Books | Prodigal Daughter | NAR |
| Pocket Books | Smokescreen | MYS |
| Signet | Carrie | HOR |
| Signet | Cujo | HOR |
| Signet | Magritte | ART |
| Signet | Organ | MUS |
+-----------------+----------------------------+------------+
28 rows in set (0.00 sec)
--------------
SELECT Nome_editore, Titolo_libro, Tipo_libro
FROM Libri as l JOIN Editori as e ON e.Codice_editore = l.Codice_editore
ORDER BY Nome_editore, Titolo_libro, Tipo_libro
--------------
+-----------------+----------------------------+------------+
| Nome_editore | Titolo_libro | Tipo_libro |
+-----------------+----------------------------+------------+
| Bantam Books | Amerika | NAR |
| Bantam Books | Castle | NAR |
| Bantam Books | Death on the Nile | MYS |
| Bantam Books | Ghost from the Grand Banks | SFI |
| Bantam Books | Hymns to the Night | POE |
| Bantam Books | Night Probe | SUS |
| Bantam Books | Shyness | PSY |
| Bantam Books | Stranger | NAR |
| Bantam Books | Vixen 07 | SUS |
| Bantam Books | Vortex | SUS |
| Best and Furrow | A Guide to SQL | COM |
| Best and Furrow | Database Systems | COM |
| Best and Furrow | dBase Programming | COM |
| Best and Furrow | DOS Essentials | COM |
| Pocket Books | Dunwich Horror and Others | HOR |
| Pocket Books | Evil Under the Sun | MYS |
| Pocket Books | First Among Equals | NAR |
| Pocket Books | Higher Creativity | PSY |
| Pocket Books | Kane and Abel | NAR |
| Pocket Books | Knockdown | MYS |
| Pocket Books | Marcel Duchamp | ART |
| Pocket Books | Prints of the 20th Century | ART |
| Pocket Books | Prodigal Daughter | NAR |
| Pocket Books | Smokescreen | MYS |
| Signet | Carrie | HOR |
| Signet | Cujo | HOR |
| Signet | Magritte | ART |
| Signet | Organ | MUS |
+-----------------+----------------------------+------------+
28 rows in set (0.00 sec)
Stesso esercizio del 09-06-09 eseguito prima in un modo e poi nell'altro. Come si fa a dire quello che è + corretto in questo caso essendo il risultato il medesimo?
Non dimentichiamoci che questa parte d'esame è pratica e che stiamo lavorando su di una delle tante implementazioni dell'SQL che opera in suo specifico modo. Questo dubbio su Order by e group by, quando sia meglio usare uno e quando l'altro vorrei togliermelo però. |
Modificato da - Nazgul in data 29/08/2009 12:16:36 |
 |
|
|
Discussione  |
|
|
|