Help su teoria Clicca QUI per vedere il messaggio nel forum |
tyrdrummer |
Ciao ragazzi devo dare un altro esame di basi di dati ma cmq l'SQL è sempre lo stesso.. non capisco una cosa di teoria e vorrei che qualcuno mi illuminasse:
il libro mi dice:
Utilizzando gli alias è possibile far riferimento a più esemplari della stessa tabella.
poi propone: estrarre gli impiegati che hanno lo stesso cognome (ma diverso nome) di impiegati del dipartimento Produzione
<code>
SELECT I1.Cognome, I1.Nome
FROM Impiegato I1, Impiegato I2
WHERE I1.Cognome = I2.Cognome AND I1.Nome <> I2.Nome AND I2.Dipart = 'Produzione'
</code>
poi mi dice:
Questa interrogazione confronta ciascuna riga di impiegato con tutte le righe di impiegato associate al dipartimento di produzione. Si osservi che in questa query ogni riga con "Produzione" come valore dell'attributo Dipart viene confrontata anche con se stessa, ma il confronto della riga con se stessa non sarà mai soddisfatto, in quanto il predicato di disuguaglianza sull'attributo Nome non potrà mai essere vero.
Qui la tabella:

Potreste gentilmente spiegarmi solo per qualche riga il ragionamento che fate? Il ragionamento che faccio non è coerente col testo del libro, quindi dato che un libro di norma è scritto bene, vi prego aiutatemi! Nello specifico quello che non mi è chiaro è come vengono valutati riga per riga... grazie mille |
TheRealCajun |
Scrivere il procedimento sarà dura, ma ci provo.
Per prima cosa vengono create due tabelle temporanee I1 e I2 (che è
il risultato dell'utilizzo degli alias).
Quindi si avrà una tabella I1 che sarà:
Mario - Rossi - Ammin - 10 - 45 - Milano
Carlo - Bianchi - Prod - 20 - 30 - Torino
...
E I2 sarà sostanzialmente identica.
Analizzando il WHERE tra le condizioni si vede che quella più facile da valutare (e anche quella che risparmia da subito un gran numero di righe) è I2.Dipart = 'Produzione', quindi io partirei da questa...dato che il dipartimento del secondo impiegato dev'essere produzione, possiamo eliminare da I2 tutti gli altri, rimanendo con:
Carlo - Bianchi - Prod - ...
Marco - Franco - Prod - ...
A questo punto si prende riga per riga I1 (che è poi la tabella completa) e si confronta con questa I2 di due righe:
1: Rossi è diverso da Bianchi, e anche da Franco...quindi non entrerà nel risultato la riga "Mario - Rossi - ...".
2: Bianchi è uguale a Bianchi, ma il nome è lo stesso (Carlo) mentre l'altra condizione impone che sia diverso; poi Bianchi è diverso da Franco quindi la riga "Carlo - Bianchi - ..." non entrerà nel risultato.
3: Verdi è diverso sia da Bianchi che da Franco...anche qui la riga non entra nel risultato.
Si continua così prendendo la riga di I1, e confrontandola prima con la prima e poi con la seconda riga di I2.
Perciò andando avanti si vede che nessun impiegato di I1 ha lo stesso cognome (ma nome diverso) di uno della tabella I2.
Dando origine all'insieme vuoto come risultato.
Spero sia chiaro il procedimento di confronto.:D |
tyrdrummer |
grazie mille tutto chiarificato, sei stato esaustivo!!
:) |
tyrdrummer |
non capisco come funziona la parola ALL nelle subquery, perchè se ho questa query:
SELECT CodImp
FROM Imp
WHERE Stipendio <= ALL (SELECT Stipendio FROM Imp)
la sub-query estrae tutti i valori da stipendio e poi come funge la where?? |
number15 |
ALL confronta con tutti i risultati presenti nella sottoquery al contrario di ANY.
La sottoquery estrae gli stipendi di tutti gli Imp e li confronta con gli stipendi di tutti gli Imp.
Il where dice che vuole che lo stipendio sia minore o uguale di tutti gli stipendi. Tradotto questa query estrae i codimp degli Imp che hanno lo stipendio più basso tra tutti gli Imp.
Se ci fosse stato solo < nel where non ci sarebbe stato alcun risultato per definizione (operi sulla stessa tabella, quindi i valori di stipendio son per forza uguali).
'Dovrebbe' essere equivalente a
SELECT CodImp
FROM Imp
WHERE Stipendio = (SELECT MIN(Stipendio) FROM Imp) |
tyrdrummer |
Originally posted by number15
ALL confronta con tutti i risultati presenti nella sottoquery al contrario di ANY.
La sottoquery estrae gli stipendi di tutti gli Imp e li confronta con gli stipendi di tutti gli Imp.
Il where dice che vuole che lo stipendio sia minore o uguale di tutti gli stipendi. Tradotto questa query estrae i codimp degli Imp che hanno lo stipendio più basso tra tutti gli Imp.
Se ci fosse stato solo < nel where non ci sarebbe stato alcun risultato per definizione (operi sulla stessa tabella, quindi i valori di stipendio son per forza uguali).
'Dovrebbe' essere equivalente a
SELECT CodImp
FROM Imp
WHERE Stipendio = (SELECT MIN(Stipendio) FROM Imp)
guarda il mio problema è che io non capisco poi in soldoni come va ad operare riga per riga.. cioè immagina che la sottoquery seleziona un po' di stipendi tipo: 80-60-45-70 come avviene il confronto? grazie mille cmq |
TheRealCajun |
Originally posted by tyrdrummer
SELECT CodImp
FROM Imp
WHERE Stipendio <= ALL (SELECT Stipendio FROM Imp)
Per fare il confronto in pratica mettiamo di avere questa tabella Imp:
CodImp - Impiegato - Stipendio
01 - Mario Rossi - 80
02 - Carlo Bianchi - 60
03 - Franco Verdi - 45
04 - Giulio Neri - 70
La sottoquery estrarra 80-60-45-70 (che sono i valori che citi tu), a questo punto fa il confronto in questo modo: prende la riga dalla prima tabella e verifica che lo stipendio di quella tupla sia minore o uguale a TUTTI i valori della sottoquery.
In pratica:
01 - Mario Rossi - 80 è minore o uguale a 80, ma non a 60, quindi già qui si ferma il confronto e questa tupla NON va nel risultato;
02 - Carlo Bianchi - 60 è minore o uguale a 80 e a 60, ma non a 45...anche questa non va nel risultato;
03 - Franco Verdi - 45 è minore o uguale a tutti i valori della sottoquery, quindi va nel risultato;
04 - Giulio Neri - 70 non andrà nel risultato.
Quindi si rimane con la tupla "03 - Franco Verdi - 45", alla quale applicando la Select si estrae "03", che è il codice degli impiegati (in questo nostro caso è uno) che percepiscono lo stipendio minore tra tutti gli impiegati.
PS: number confermo che la query alternativa che hai proposto (quella con "= select MIN") è equivalente. |
number15 |
Allora facciam esempio:
Questa è la tabella Imp (solo cod e stipendio)
1 2000€
2 3000€
3 2000€
4 2500€
5 2300€
La subquery (SELECT Stipendio FROM Imp) restituisce:
2000
3000
2000
2500
2300
Ogni stipendio della prima query verrà confrontato con ogni stipendio della subquery: se è <= allora verrà restituito il codimp.
Partiamo dal primo:
2000 <= 2000? Si
2000 <= 3000? Si
2000 <= 2000? Si
2000 <= 2500? Si
2000 <= 2300? Si
Visto che 2000 è <= di tutti gli stipendi allora codimp 1 viene preso.
Per codimp2:
3000 <= 2000? No (Qua non so se termina subito i confronti o se confronta anche con gli altri stipendi, nonostante il primo risultato sia già falso. Non cambia niente ai fini dello studio)
Codimp 3:
2000 <= 2000? Si
2000 <= 3000? Si
2000 <= 2000? Si
2000 <= 2500? Si
2000 <= 2300? Si
Coimp viene preso.
Stessi passaggi vengono fatti anche per gli altri valori.
Il risultato della query sarà:
1
3 |
number15 |
Ecco anticipato :D |
TheRealCajun |
Originally posted by number15
Ecco anticipato :D
Bhe buona così, almeno ha due esempi diversi.:-D |
tyrdrummer |
quindi in soldoni invece con l'any basta che uno sia vero e non si mette a vedere se sono tutti veri giusto? poi mi sembra che l'any sia l'equivalente di IN .
Vi ringrazio per le vostre spiegazioni e scusate il disturbo!
:) |
number15 |
Sì, per l'ANY basta che il confronto sia soddisfatto per almeno un elemento della subquery.
Sì, '= ANY' è equivalente ad 'IN'. |
|
|
|