View Full Version : Rudimenti di SQL
ingmotty
25-02-2008, 15:54
Ciao a tutti, sto preparando l'esame di sistemi informativi che nella prova scritta prevede delle interrogazioni a delle basi di dati elementari.
Il guaio è che con i linguaggi di programmazione in generale non sono andato mai troppo daccordo e quindi vi chiedo l'immenso favore di aiutarmi.
Detto questo l'esercizio che devo svolgere è il seguente illustrato:
http://img217.imageshack.us/img217/4037/immagineto9.jpg
Ora lo schema relazionale per la precedente base di dati in base a quanto ho letto e sono riuscito ad imparare è il seguente:
ZONE(Zona, Nome zona)
RISTORANTI(Cod, Nome, Indirizzo, Tipo, Zona)
CUCINE(Tipo,DescrTipo)
CONVENZIONI(Cod,CodCarta)
CARTE DI CREDITO(CodCarta,Carta)
Ho Sottolineato gli attributi che costituiscono i vincoli di ciascuna relazione.
Per quanto riguarda al secondo punto, ovvero l'interrogazione in SQL, non sono da dove partire.
Spero che mi possiate aiutare. :cheers:
khelidan1980
25-02-2008, 15:59
ok ma che interrogazione devi fare?O son rimbambito io o non lo hai scritto! :)
La traduzione nello schema relazionale è corretta, ma come diceva khelidan1980 per poterti aiutare è necessario sapere cosa ti chiede di determinare l'interrogazione (l'illustrazione è tagliata proprio sulla definizione dell'interrogazione).
ingmotty
25-02-2008, 16:21
Avete ragione non me ne sono accorto ho sostituito l'immagine nel primo post con il quesito completo.
_Claudio
25-02-2008, 17:05
Se ben ricordo dovresti fare:
select nome,indirizzo from ristoranti
where zona like
select zona from zone
where nomezona like
select zona from ristoranti
where nome like 'nomeassegnato'
Ok....
allora, se non ho capito male, assegnato un ristorante, si vogliono determinare nome e indirizzo degli altri ristoranti presenti nella stessa zona.
SELECT Nome,Indirizzo fai la proiezione degli attributi che ti servono
FROM ristoranti dalla relazione di interesse
WHERE Zona =ANY
(SELECT Zona relativamente alle ennuple la cui zona è uguale
FROM ristoranti a quella di un ristorante presente nella relazione "ristoranti"
WHERE [selezione del ristorante assegnato]
) che risponde a quello assegnato
Correggetemi se sbaglio.
ingmotty
25-02-2008, 17:14
Ciao mille grazie per la risposta ma una cosa che non mi era chiara nel testo del quesito è cosa intendesse per query innestate.
Nel senso che chiedeva di esprimere la query come ha fatto attix ossia utilizzando un'interrogazione nidificata?
Ciao mille grazie per la risposta ma una cosa che non mi era chiara nel testo del quesito è cosa intendesse per query innestate.
Ciao :)
Le query innestate o nidificate sono query che richiamano all'interno della clausola WHERE un'altra query come condizione di selezione.
Innestate o nidificate mi pare siano la stessa cosa.
Ognuno le chiama come più gli piace :D
ingmotty
25-02-2008, 22:19
Ho capito, il mio testo parlava di qury nidificate e leggendo invece l'esercizio avevo trovato un pò di difficoltà.
In ogni caso se l'eserzio non avesse chiesto specificamente query nidificate, sarebbe stata giusta anche l'interrogazione di Claudio giusto?
Ho capito, il mio testo parlava di qury nidificate e leggendo invece l'esercizio avevo trovato un pò di difficoltà.
In ogni caso se l'eserzio non avesse chiesto specificamente query nidificate, sarebbe stata giusta anche l'interrogazione di Claudio giusto?
select nome,indirizzo from ristoranti
where zona like
select zona from zone
where nomezona like
select zona from ristoranti
where nome like 'nomeassegnato'
Ti dirò...l'operatore LIKE lo uso per confronti su stringhe parziali (che so...ad esempio se avesse chiesto la zona di tutti i ristoranti che i cui nomi iniziano per "A").
Personalmente eviterei di usarlo in questa circostanza. ;)
La SELECT in grassetto, poi , va omessa sia perchè inutile, sia perchè confronta due attributi di tipo diverso (l'attributo NomeZona in zone, che è una stringa, e l'attributo Zona in ristoranti che è un carattere). ;)
_Claudio
26-02-2008, 18:28
select nome,indirizzo from ristoranti
where zona like
select zona from zone
where nomezona like
select zona from ristoranti
where nome like 'nomeassegnato'
Ti dirò...l'operatore LIKE lo uso per confronti su stringhe parziali (che so...ad esempio se avesse chiesto la zona di tutti i ristoranti che i cui nomi iniziano per "A").
Personalmente eviterei di usarlo in questa circostanza. ;)
La SELECT in grassetto, poi , va omessa sia perchè inutile, sia perchè confronta due attributi di tipo diverso (l'attributo NomeZona in zone, che è una stringa, e l'attributo Zona in ristoranti che è un carattere). ;)
Si, hai ragione, è vero, sono un bel po' arrugginito con sql (anche perchè oggi come oggi nessuno scrive più query SQL dopo aver passato il corso di Basi di Dati...)
ingmotty
26-02-2008, 18:40
(anche perchè oggi come oggi nessuno scrive più query SQL dopo aver passato il corso di Basi di Dati...)
Ecco spero di passarlo al più presto per scordarmelo anch'io.:D
_Claudio
27-02-2008, 10:57
Ecco spero di passarlo al più presto per scordarmelo anch'io.:D
Io non l'ho imparato nemmeno per l'esame, era pieno di errori ma il concetto era giusto... ma il mio porcovotone l'ho preso comunque :sofico:
astorcas
27-02-2008, 11:00
Si, hai ragione, è vero, sono un bel po' arrugginito con sql (anche perchè oggi come oggi nessuno scrive più query SQL dopo aver passato il corso di Basi di Dati...)
Ti riferisci all'università o per tutta la vita?
_Claudio
29-02-2008, 16:30
Ti riferisci all'università o per tutta la vita?
Per tutta la vita ovviamente... a meno che non farai software che si interfacciano con i DB o sistemi informativi...
ingmotty
06-03-2008, 20:02
Ragazzi gentilmente Potreste controllarmi la query relativa a questo esercizio?
http://img85.imageshack.us/img85/9755/immaginedq1.jpg
IO ho scritto:
Select R1 NOME, R2 INDIRIZZO
FROM RISTORANTI R1, RISTORANTI R2,ZONE
WHERE R1.ZONA=ZONE.ZONA AND
R2.ZONA=ZONE.ZONA AND
R1.ZONA=R2.ZONA
La base dati è sempre quella nel mio primo post.
Mille grazie come sempre per l'aiuto.
Non e' giusta purtroppo.
Prova a svolgere questo, che e' davvero vicino:
Trovare tutti i ristoranti che sono nella stessa zona del ristorante che si chiama "Pippo"
ingmotty
06-03-2008, 22:34
:( mannaggia, non capisco dovè che sbaglio.:mc:
gugoXX Non riesco a capire il tuo suggerimento,per favore mi potresti spiegare?
Nel senso di provare a rispondere alla mia di domanda, non a quella dell'esercizio... che pero' e' la stessa cosa detta in modo piu' "umano"
ingmotty
06-03-2008, 22:52
Ma anche la tua query prevede l'impiego di rinominazione?
Non preoccuparti di cosa prevede (lo prevede se la scrivi in un modo, non la prevede se la scrivi in un altro), prova a rispondere.
ingmotty
06-03-2008, 23:05
Non riesco a trovare il modo di formulare la giusta interrogazione. Intuisco che necessita di query nidificate ma non trovo la formula giusta. :(
ingmotty
06-03-2008, 23:08
Aspetta forse è così?
SELECT *
FROM RISTORANTI
WHERE ANY = (SELECT ZONA
FROM RISTORANTI
WHERE RISTORANTE='PIPPO')
E' giusta?
Aspetta forse è così?
SELECT *
FROM RISTORANTI
WHERE ANY = (SELECT ZONA
FROM RISTORANTI
WHERE RISTORANTE='PIPPO')
E' giusta?
quasi, ANY non c'entra, basta mettere
SELECT *
FROM RISTORANTI
WHERE ZONA = (SELECT ZONA
FROM RISTORANTI
WHERE RISTORANTE='PIPPO')
E non hai praticamente risposto alla domanda? Basta che non metti * ma metti solo le cose che chiede.
Hai usato 2 istanze della ristoranti (era un suggerimento, non si puo' fare altrimenti)
Hai trovato il modo di farlo senza "rinominazione"
ingmotty
06-03-2008, 23:18
Ok grazie mille ma il testo dell'esercizio mi richiede espressamenti di creare la query utilizzando la rinominazione.
In questo caso come mi devo comportare?
Eh, non lo diceva.
Comunque e' sufficiente fare la JOIN tra le due tabelle ristoranti, mediante la colonna che hai messo prima nella clausola =, ovvero la zona.
La zona della prima tabella ristoranti deve essere uguale alla zona della seconda tabella ristoranti (che e' proprio il testo dell'esercizio, devono essere nella stessa zona...)
ingmotty
07-03-2008, 09:26
Scusami ma il testo dice "usando due istanze della relazione Ristoranti".
Questo non significa che devo rinominare la relazione ristoranti?:confused:
Scusami ma il testo dice "usando due istanze della relazione Ristoranti".
Questo non significa che devo rinominare la relazione ristoranti?:confused:
Non direi, significa solo che devi usare due volte la tabella ristoranti...
Sia la soluzione che hai trovato te che quella con la "rinomina" prevedono di usare 2 volte la tabella ristoranti, pertanto secondo me avresti risolto l'esercizio anche cosi'.
Sarebbe comunque meglio non chiamarla soluzione con la "rinomina". Sarebbe meglio chiamarla soluzione con una join, oppure meglio ancora soluzione con una
"selfjoin sulla tabella ristoranti"
Che prevede per forza la rinomina delle 2 tabelle coinvolte, per poter identificare i campi di ciascuna delle due istanza.
ingmotty
07-03-2008, 09:59
Quindi:
SELECT NOME,INDIRIZZO
FROM RISTORANTI
WHERE ZONA=( SELECT ZONA
FROM RISTORANTI
WHERE RISTORANTE='NOME RISTORANTE')
Va bene?
Io direi quasi di si'.
WHERE ZONA=( SELECT ZONA
= qui non va bene perche' non sei sicuro che la inner query restituisca un solo record.
Potrebbero esserci 2 ristoranti che si chiamano "nome ristorante", magari appartenenti a 2 zone diverse. In questo caso avresti un errore durante l'esecuzione.
Al posto dell = io metterei la clausola IN
ovvero
SELECT NOME,INDIRIZZO
FROM RISTORANTI
WHERE ZONA IN ( SELECT ZONA
FROM RISTORANTI
WHERE RISTORANTE='NOME RISTORANTE')
In questo modo se il ristorante che si chiama 'nome ristorante' fosse solo 1, allora questa query risponderebbe esattamente alla domanda richiesta.
Ma e' resistente al caso 2 o piu'.
Questa query risponderebbe effettivamente alla domanda:
Dire Nome e Indirizzo di tutti i ristoranti che sono nella zona di uno dei ristoranti che si chiama 'NOME RISTORANTE'.
ingmotty
07-03-2008, 10:35
Ok grazie mille, mi sei stato di immenso aiuto. :cincin:
ingmotty
12-03-2008, 17:05
Mi ritorovo con la seguente basi di dati don relativo quesito sottostante
http://img520.imageshack.us/img520/2640/immaginese7.jpg
Per favore qualcuno mi potrebbe dare una mano a scrivere la query?
La tabella Genere non serve per la domanda.
Sono coinvolte solo le altre 3.
Una join secca tra le 3 tabelle con una ORDER BY in fondo...
ingmotty
12-03-2008, 18:25
Ma nella clausola select devo inserire soltato l'attributo Titolo?
Io avevo scritto questo:
Select Titolo
from Libri
where Cod_libro=( select cod_libro
from Aut_Libri
group by Id_aut )
ingmotty
12-03-2008, 18:33
La join secondo le tue indicazioni è questa?
SelectLibri.titolo
from Autori,Aut_libri,Libri
Where libri.Cod_libro=Aut_Libri.cod_libro And
Aut_libri.id_autore=Autori.cod_fisc
Order by Autori.nome
La join secondo le tue indicazioni è questa?
SelectLibri.titolo
from Autori,Aut_libri,Libri
Where libri.Cod_libro=Aut_Libri.cod_libro And
Aut_libri.id_autore=Autori.cod_fisc
Order by Autori.nome
si' :D
Mettici anche il nome dell'autore nella select, senno' sara' anche ordinato, ma chi legge il risultato non lo sa.
ingmotty
12-03-2008, 19:10
Ok capo.:mano:
ingmotty
12-03-2008, 19:12
C'è una cosa che non sono ancora riuscito a capire, ovvero quando si devono usare le join e quando invece bisogna ricorrere alle query nidificate.:confused:
C'è una cosa che non sono ancora riuscito a capire, ovvero quando si devono usare le join e quando invece bisogna ricorrere alle query nidificate.:confused:
Non c'e' una ricetta direi.
Quando devi tirare fuori dati da una tabella sola, mettendo al limite clausole di esistenza o di o di filtro sulla base di dati di una o piu' altre tabelle allora va bene con la IN o la EXISTS e le subquery
Quando devi tirare fuori dati di piu' tabelle, correlati insieme, non puoi non ricorrere alle join.
Es: la tua era
"Per ogni autore restituire l'elenco dei suoi libri, ordinando il tutto per nome dell'autore"
Ora, il nome dell'autore sta da una parte, i libri dall'altra.
Anche volendo restituire i soli libri, li devo ordinare per nome dell'autore. Anche come colonna nascosta deve esistere (per poter fare la orderby)
Devo restituire dati di piu' tabelle contemporaneamente -> Join
Se fosse stato invece:
"Restituire i libri dei quali si sa l'autore",
che e' valida, supponendo che possano esistere libri non presenti nella tabella aut_libri,
poiche' dovro' restituire dati da una tabella sola (libri)
allora ho diverse strade.
La join:
SELECT DISTINCT Titolo
FROM Libri JOIN Aut_Libri ON (Libri.cod_libro=Aut_Libri.cod_libro)
oppure la IN
Select Titolo FROM Libri
WHERE cod_libro IN
(SELECT cod_libro FROM Aut_Libri)
oppure la Exists
SELECT Titolo FROM Libri
WHERE exists (SELECT 1 FROM Aut_Libri WHERE Libri.cod_libro=Aut_Libri.cod_libro)
Le ultime 2 e' molto probabile che vengano risolte con lo stesso piano di esecuzione dall'ottimizzatore
PS: SQL e' uno dei cosiddetti linguaggi di quarta generazione, ed e' anche di quelli dichiarativi. Uno di quei linguaggi in cui dici cosa vuoi che il computer faccia, senza dirgli veramente cosa fare, ma lasciando a lui la ricerca dell'algoritmo giusto. Per questo puo' capitare diversi statement possono essere eseguiti nello stesso modo.
ingmotty
14-03-2008, 14:56
Ho capito sei stato chiarissimo.
Ora c'è quest'altro esercizio che non riesco proprio a capire cosa voglia:
http://img219.imageshack.us/img219/2186/immagineru7.jpg
Potreste illuminarmi?:help:
Trova una query che ti restituisca tante righe quante sono le righe di scontrino, avente come colonne di dato la quantita' venduta e il totale di incasso per quella singola riga (che e' un calcolo fatto su colonne che arrivano da 2 tabelle diverse, quindi... )
dopodiche' lavorando con le SUM e le GROUP BY su questa query potrai ottenere il risultato richiesto.
Ti consiglio di lavorare, fino a qui, solo con gli ID delle persone. Alla fine, e solo alla fine, potrai andare a recuperare il cognome.
ingmotty
14-03-2008, 15:18
Potresti riformulare? Chi è scontrino?
Che debba ricorrere alla join adesso l'ho capito. :)
ingmotty
14-03-2008, 15:40
Allora io nel frattempo ho scritto questo:
select Rappresentanti.cognome, Sum(Dettordini.quantità), sum(Dettordini.quantità*Prodotti.prezzo unitario)
From Rappresentanti, dettordini, prodotti, ordini
Where Dettordini.Idprod=Prodotti.Idprod AND
Ordini.Idrap=Rapprensentanti.Idrapp
group by Rappresentanti.Cognome
Scontrini avrebbe voluto essere la tabella di dettaglio degli ordini :D
E' quasi buono.
Manca una join. Hai messo in join
A con B
C con D
manca ancora una clausola
ingmotty
14-03-2008, 17:05
select Rappresentanti.cognome, Sum(Dettordini.quantità), sum(Dettordini.quantità*Prodotti.prezzo unitario)
From Rappresentanti, dettordini, prodotti, ordini
Where Dettordini.Idprod=Prodotti.Idprod AND
Ordini.Idrap=Rapprensentanti.Idrapp AND
Dettordini.idord=Ordini.Idord
group by Rappresentanti.Cognome
Così?:p
Benissimo.
Metti solo gli alias alle colonne SUM
Voto? 9.
Perche'? Perche' se due Rappresentanti hanno lo stesso cognome tu li fai collassare insieme, e restituisci i dai di entrambi sulla stessa riga, indistinti.
L'esercizio secondo me lo puoi considerare finito, il resto e' per la lode, se vuoi...
ingmotty
14-03-2008, 21:44
Ok capo grazie mille.Sei impareggiabile.:cincin:
ingmotty
06-05-2008, 19:58
Dovrei rispondere alla seguente query:
http://img240.imageshack.us/img240/7657/immaginecr5.jpg
Ma non miè ben chiaro cosa mi sta chiedendo, mi potreste dare qualche suggerimento?
MA non e' esattamente quella di 15 giorni fa, che avevi gia' risolto?
ingmotty
06-05-2008, 21:41
MA non e' esattamente quella di 15 giorni fa, che avevi gia' risolto?
Hai ragione in pieno il fatto è che abbiamo sostenuto la prima parte dell'esame, in rete di comunicazioni e ho trascurato un pò la parte di programmazione in SQL :doh:.
Ora ho ripreso e non mi aspettavo di essermi così arruginito. Certo che la programmazione si pfa presto a scordare.
ingmotty
11-05-2008, 19:12
Dunque tenedo conto della tua osservazione la query dovrebbe essere così giusto?
select Rappresentanti.cognome, Sum(Dettordini.quantità) as Totalequantità, sum(Dettordini.quantità*Prodotti.prezzo unitario) as Prezzo totale
From Rappresentanti, dettordini, prodotti, ordini
Where Dettordini.Idprod=Prodotti.Idprod AND
Ordini.Idrap=Rapprensentanti.Idrapp AND
Dettordini.idord=Ordini.Idord
group by Rappresentanti.Cognome
ingmotty
12-05-2008, 16:19
UP:p
Si, corretto, a parte che gli alias non possono avere spazi in mezzo, quindi PrezzoTotale
ingmotty
12-05-2008, 22:09
Ok grazie mille di tutto. A buon rendere.:cincin:
speriamo che lunedì vada bene.:D
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.