Sara' sicuramente una cavolata ma non sto riuscendo a capire la differenza tra il prodotto cartesiano (cross join) ed il join semplice (che credo sia il join interno), quello con sintassi
Codice: Seleziona tutto
SELECT qualcosa
FROM tabella1 JOIN tabella2 ON chiave1 = chiave2
WHERE condizione
Codice: Seleziona tutto
SELECT qualcosa
FROM tabella1 AS tab1, tabella2 AS tab2
WHERE tab1.chiave1 = tab2.chiave2
Ho notato che negli ultimi appelli della mia facolta', come ad esempio quello del 20.01.2009 (che allego in fondo al topic), la maggior parte delle query SQL vengono risolte utilizzando la sintassi con le virgole, anche se a me verrebbe naturale utilizzare la sintassi con JOIN.
Ad esempio, l'esercizio 3.B dell'appello del 20.01.2009 richiede: "Selezionare in SQL i cognomi delle persone che spendonp piu' di 700 euro in corsi"
e viene risolta con:
Codice: Seleziona tutto
SELECT P.Cognome
FROM Persona P, Iscrizione I, Corso C
WHERE P.ID = I.Persona AND I.Corso = C.Nome
GROUP BY ID, Cognome
HAVING SUM(Prezzo) > 700
Oppure e' qualcosa di diverso?
Io l'avrei scritta cosi:
Codice: Seleziona tutto
SELECT P.Cognome
FROM Persona P JOIN Iscrizione I ON P.ID = I.Persona JOIN Corso C ON I.Corso = C.Nome
GROUP BY ID, Cognome
HAVING SUM(Prezzo) > 700
Codice: Seleziona tutto
SELECT Cognome
FROM Persona JOIN Iscrizione ON Persona.ID = Iscrizione.Persona JOIN Corso ON Iscrizione.Corso = Corso.Nome
GROUP BY ID, Cognome
HAVING SUM(Prezzo) > 700
Ho trovato questa guida secondo la quale le due sintassi sono equivalenti...o almeno cosi' credo di aver capito: http://database.html.it/guide/lezione/2 ... elle-join/
Cito alcuni pezzi:
Quindi a me verrebbe da pensare che la sintassi con le virgole si puo' utilizzare, per comodita' (anche se la trovo piu' complicata), quando il campo WHERE non deve essere usato per una condizione che riduca l'output della query, e viene usato invece essere usato per indicare le chiavi tramite cui joinare le tabelle; la sintassi col JOIN invece va utilizzata quando il campo WHERE ci serve ai fini del risultato della query.La inner join si effettua andando a cercare righe corrispondenti nelle due tabelle, basandosi sul valore di determinate colonne.
Immaginiamo, in un esempio classico, di avere una tabella ordini e una tabella clienti. Diciamo che la prima contiene le colonne idOrdine, idCliente, articolo, quantità mentre la seconda contiene idCliente, nome, cognome.
Evidentemente il campo 'idCliente' della tabella ordini è una chiave esterna sulla tabella clienti, che ci permette di recuperare i dati anagrafici del cliente che ha effettuato l'ordine (abbiamo limitato al minimo, per semplicità, il numero dei campi contenuti nelle due tabelle). In questo caso quindi potremo fare le join basandoci sulla corrispondenza dei valori dei campi 'idCliente' nelle due tabelle (naturalmente non è necessario che le colonne abbiano lo stesso nome).
Vediamo alcuni esempi:
SELECT * FROM ordini AS o, clienti AS c WHERE o.idCliente = c.idCliente AND idOrdine > 1000;
SELECT * FROM ordini AS o JOIN clienti AS c on o.idCliente = c.idCliente WHERE idOrdine > 1000;
Queste due query sono equivalenti e rappresentano una inner join: estraggono i dati relativi ad ordine e cliente per quegli ordini che hanno un identificativo maggiore di 1000. La prima è una join implicita: infatti non l'abbiamo dichiarata esplicitamente e abbiamo messo la condizione di join nella clausola WHERE. Quando elenchiamo più tabelle nella FROM senza dichiarare esplicitamente la JOIN stiamo facendo una inner join (oppure una cross join se non indichiamo condizioni di join nella WHERE).
Nella seconda, al posto di 'JOIN' avremmo potuto scrivere per esteso 'INNER JOIN'; in alcune vecchie versioni di MySQL ciò è obbligatorio.
SELECT * FROM ordini as o LEFT JOIN clienti as c ON o.idCliente = c.idCliente WHERE idOrdine > 1000;
Ho pensato anche che la sintassi con le virgole rappresenti il prodotto cartesiano quando le tabelle non hanno delle colonne in comune (intendo con dati in comune, ad esempio Cliente.ID e Abbonamento.Cliente) e quindi non e' comunque possibile joinarle.
In questo caso il campo WHERE rimarrebbe libero per essere usato per la condizione della query.
Se il campo WHERE collega delle chiavi allora e' un join
Vaneggio?
Virgole e JOIN sono esattamente la stessa cosa o sono due cose completamente diverse?
E'giusto il mio ragionamento sul campo WHERE usato al posto della specifica ON per indicare le chiavi da usare per il join?
Il prodotto cartesiano (cross join) quando va usato? A me sembre che negli esercizi sia sempre possibile utilizzare il JOIN...
Ed infine, quando si usa il termine JOIN senza specifiche ulteriori, di che tipo di JOIN si tratta? Del join interno come dice la guida di html.it?
Non e' che qualcuno di voi ha qualche link un po' piu' comprensibile su questo argomento?
Spero che sappiate aiutarmi almeno voi; ho chiesto un po' in giro ma ogni volta ricevo una versione diversa.
Sono gia' diversi giorni che mi ci sto confondendo ed e' veramente fondamentale che io riesca a capire chiaramente la differenza fra le varie sintassi ed i vari join da utilizzare negli esercizi.
Grazie!
Appello 2009.01.20, parte SQL



