Unione, Intersezione, Differenza 19/12/2015 Operazioni booleane su tabelle A volte può essere utile poter ottenere un’unica tabella contenente alcuni dei dati contenuti in due tabelle omogenee, ossia con attributi definiti sullo stesso dominio. Per esempio date le tabelle: Maternità Paternità PADRE FIGLIO Sergio Franco Luigi Olga Luigi Filippo Franco Andrea Franco Aldo 19/12/2015 MADRE FIGLIO Luisa Maria Luisa Luigi Anna Olga Anna Filippo Maria Andrea Maria Aldo Potrebbe essere utile poter svolgere su di esse delle operazioni booleane, calcolando unione, intersezione e differenza. Unione, intersezione e differenza In SQL la SELECT da sola non permette di fare questo tipo di operazioni su tabelle. Esistono per questo dei costrutti espliciti che utilizzano le parole chiave UNION INTERSECT EXCEPT (in oracle MINUS) Tali operatori lavorano sulle tabelle come se fossero insiemi di righe, dunque i duplicati vengono eliminati (a meno che si usi la specifica ALL) anche dalle proiezioni! 19/12/2015 Unione L’operatore UNION realizza l’operazione di unione definita nell’algebra relazionale. Utilizza come operandi le due tabelle risultanti da comandi SELECT e restituisce una terza tabella che contiene tutte le righe della prima e della seconda tabella. Nel caso in cui dall’unione e dalla proiezione risultassero delle righe duplicate, l’operatore UNION ne mantiene una sola copia, a meno che non sia specificata l’opzione ALL che indica la volontà di mantenere i duplicati SELECT … UNION [all] SELECT ... 19/12/2015 Notazione posizionale! SELECT padre FROM paternita UNION SELECT madre FROM maternita quali nomi per gli attributi del risultato? nessuno quelli del primo operando … In SQL-oracle quelli del primo operando 19/12/2015 Paternità PADRE FIGLIO Sergio Franco Luigi Olga Luigi Filippo Franco Andrea Franco Aldo Maternità MADRE FIGLIO Luisa Maria Luisa Luigi Anna Olga Anna Filippo Maria Andrea Maria Aldo 19/12/2015 SELECT padre, figlio FROM paternita UNION SELECT madre, figlio FROM maternita PADRE FIGLIO Sergio Franco Luigi Olga Luigi Filippo Franco Andrea Franco Aldo Luisa Maria Luisa Luigi Anna Olga Anna Filippo Maria Andrea Maria Aldo Notazione posizionale, 2 SELECT Padre, Figlio FROM paternita UNION SELECT Figlio, Madre FROM maternita L’attributo Padre della prima Select viene messo nella stessa colonna con l’attributo Figlio della seconda select 19/12/2015 Paternità PADRE FIGLIO Sergio Franco Luigi Olga Luigi Filippo Franco Andrea Franco Aldo Maternità MADRE FIGLIO Luisa Maria Luisa Luigi Anna Olga Anna Filippo Maria Andrea Maria Aldo 19/12/2015 SELECT Padre, Figlio FROM paternita UNION SELECT Figlio, Madre FROM maternita PADRE FIGLIO Sergio Franco Luigi Olga Luigi Filippo Franco Andrea Franco Aldo Maria Luisa Luigi Luisa Olga Anna Filippo Anna Andrea Maria Aldo Maria Notazione posizionale, 2 SELECT Padre, Figlio FROM paternita UNION SELECT Figlio, Madre FROM maternita SELECT Padre, Figlio FROM paternita UNION SELECT Madre, Figlio FROM maternita L’attributo Padre della prima Select viene messo nella stessa colonna con l’attributo Figlio della seconda select L’attributo Padre della prima Select viene messo nella stessa colonna con l’attributo Madre della seconda select 19/12/2015 Notazione posizionale, 3 Anche con le ridenominazioni non cambia niente. La seguente istruzione non è semanticamente corretta: SELECT padre as genitore, figlio FROM paternita UNION SELECT figlio, madre as genitore FROM maternita 19/12/2015 Paternità PADRE FIGLIO Sergio Franco Luigi Olga Luigi Filippo Franco Andrea Franco Aldo Maternità MADRE FIGLIO Luisa Maria Luisa Luigi Anna Olga Anna Filippo Maria Andrea Maria Aldo 19/12/2015 SELECT padre as genitore, figlio FROM paternita UNION SELECT figlio, madre as genitore FROM maternita GENITORE FIGLIO Sergio Franco Luigi Olga Luigi Filippo Franco Andrea Franco Aldo Maria Luisa Luigi Luisa Olga Anna Filippo Anna Andrea Maria Aldo Maria Notazione posizionale, 3 Sbagliata SELECT padre as genitore, figlio FROM paternita UNION SELECT figlio, madre as genitore FROM maternita Corretta: SELECT padre as genitore, figlio FROM paternita UNION SELECT madre as genitore, figlio FROM maternita 19/12/2015 Notazione posizionale Quanto detto riguardo alla notazione posizionale dell’operatore UNION vale equivalentemente per gli altri operatori booleani EXCEPT (Minus in Oracle) e INTERSECT. 19/12/2015 Differenza L’operatore MINUS (in Oracle) utilizza come operandi due tabelle ottenute mediante due select e ha come risultato una nuova tabella che contiene tutte le righe della prima che non si trovano nella seconda. Realizza la differenza dell’algebra relazionale. Anche qui si può specificare l’opzione ALL per indicare la volontà di mantenere i duplicati. Sintassi: SELECT … MINUS [ALL] SELECT … 19/12/2015 Except, esempio Impiegati il cui nome che non coincide col cognome di qualche altro impiegato Nota che la differenza può essere effettuata da un’unica select che utilizza subselect 19/12/2015 SELECT Nome FROM Impiegato EXCEPT SELECT Cognome as Nome FROM Impiegato SELECT nome FROM Impiegato WHERE nome<>All(SELECTcognome FROM Impiegato) Intersezione L’operatore INTERSECT utilizza come operandi due tabelle risultanti dai comandi SELECT e restituisce una tabella che contiene le righe comuni alle due tabelle iniziali. Realizza l’intersezione dell’algebra relazionale. Sintassi SELECT … INTERSECT [ALL] SELECT … L’opzione ALL serve a mantenere gli eventuali duplicati di righe. In sua assenza, si mantiene una sola copia delle righe duplicate. 19/12/2015 Intersect, esempio Gli impiegati il cui nome è anche il cognome di qualcun altro SELECT Nome FROM Impiegato INTERSECT SELECT Cognome as Nome FROM Impiegato equivale a SELECT I.Nome FROM Impiegato I, Impiegato J WHERE I.Nome = J.Cognome 19/12/2015 Esercizio Elencare i codici degli articoli con prezzo superiore a 1000 euro insieme a quelli composti da meno di 10 componenti Select art_cod From Articoli Where art_prezzo> 1000 UNION Select art_cod From Compart Group by art_cod Having sum(compart_qta)<10 19/12/2015 Esercizio Elencare i codici degli ordini del negozio con codice 0040 per cui vengono richiesti più di 10 pezzi dello stesso articolo Select ord_cod From Ordini Where neg_cod=‘0040’ INTERSECT Select ord_cod From Ordart Where ordart_qta>10 19/12/2015 Esercizio Elencare i codici degli articoli di cui sono stati ordinati piu di 10 pezzi, tranne quelli nella cui composizione c’è una componente di tipo Anta Select art_cod From Ordart Group by (art_cod) Where sum(ordart_qta)>10 MINUS Select art_cod From Compart NATURAL JOIN Componenti Where com_descrizione LIKE ‘%Anta%’ 19/12/2015 Esercizio Scrivere i nomi degli articoli per cui sono stati fatti degli ordini da Firenze e nella cui composizione c’è un montante laterale Select art_descrizione From Articoli, ordart, ordini, Negozi Where Articoli.art_cod=ordart.Art_cod and Ordart.ord_cod=ordini.ord_cod and ordini.neg_cod=Negozi.neg_cod and neg_citta=‘Firenze’ Intersect Select art_descrizione From Articoli, Compart, Componenti Where articoli.art_cod=compart.art_cod Compart.com_cod=componenti.com_cod 19/12/2015 and com_descrizione like ‘%montante laterale%’ Esercizio Scrivere i nomi dei laboratori che producono componenti che sono utilizzati sia nell’articolo ‘Libreria 100 cm x 120 cm’ che nell’articolo ‘Libreria 200 cm x 120 cm’ Select lab_nome From Laboratori L, Componenti C, compart CA, Articoli A Where L.lab_cod=C.lab_cod AND C.com.com_cod=CA.com_cod AND CA.Art_cod=A.art_cod AND art_descrizione= ‘Libreria 100 cm x 120 cm’ INTERSECT Select lab_nome From Laboratori L, Componenti C, compart CA, Articoli A Where L.lab_cod=C.lab_cod AND C.com.com_cod=CA.com_cod AND CA.Art_cod=A.art_cod AND 19/12/2015 art_descrizione= ‘Libreria 200 cm x 120 cm’ Esercizio Scrivere i nomi dei laboratori che producono componenti che sono utilizzati in ‘Libreria 200 cm x 120 cm’ che non sono utilizzati in ‘Libreria 200 cm x 120 cm’ Select lab_nome From Laboratori L, Componenti C, compart CA, Articoli A Where L.lab_cod=C.lab_cod AND C.com.com_cod=CA.com_cod AND CA.Art_cod=A.art_cod AND art_descrizione= ‘Libreria 100 cm x 120 cm’ MINUS Select lab_nome From Laboratori L, Componenti C, compart CA, Articoli A Where L.lab_cod=C.lab_cod AND C.com.com_cod=CA.com_cod AND CA.Art_cod=A.art_cod AND 19/12/2015 art_descrizione= ‘Libreria 200 cm x 120 cm’ Esercizio Visualizzare una tabella con la descrizione e il costo di ogni articolo che è stato ordinato da negozi di Roma, e di ogni componente che è stata prodotta in Laboratori di Firenze. Select art_descrizione Merce, art_prezzo Costo From Articoli join ordart using(art_cod) join Ordini using (ord_cod) join negozi using (neg_cod) Where neg_citta = ‘Roma’ UNION Select com_descrizione, com_costo From Componenti Where lab_cod IN (select lab_cod FROM Laboratori where Lab_Città=‘Firenze’ 19/12/2015