Guida [GUIDA] Basi di dati - SQL

Stato
Discussione chiusa ad ulteriori risposte.

syscall

Utente Emerald
21 Settembre 2013
683
43
581
475
Ultima modifica da un moderatore:
Inforgiani buon pomeriggio, sono sempre io, la vostra system call (scegliete voi quale) :-D

Era il 29 settembre quando decisi di iniziare questo nuovo argomento (subito dopo sistemi operativi), e' passato un po' ma sono soddisfatto, oggi infatti chiuderemo la questione parlando di SQL, che sara' l'ultima guida riguardante appunto basi di dati! Sperando di non deludere le vostre aspettative che dire.. buona lettura !!

Yeah, Bene hacari, siamo giunti alla fine della nostra serie di guide sulle basi di dati, come detto qualche riga sopra, oggi parleremo del tanto atteso SQL, o almeno ci proviamo!

L'SQL e' un linguaggio per la gestione delle basi di dati e sostanzialmente comprende sia la base di DDL che di DML, ovvero contiene istruzioni per la Data Definition Language (definizione dei dati) e Data Manipulation Language (manipolazione dati), dove per manipolazione intendiamo interrogazione e aggiornamento dei dati.

SQL sta per Structured Query Language, ed e' sostanzialmente uno standard de facto (De facto - Wikipedia).

Consideriamo che il precedente linguaggio visto nelle nostre guide qui su inforge, ovvero l'algebra relazionale era un linguaggio sostanzialmente teorico, l'SQL e' invece un linguaggio usato nella pratica in maniera totalmente diffusa, tipicamente e' infatti "lo standard".

Iniziamo col vedere le istruzioni principali, anzi, l'istruzione principale della sezione relativa alla definizione dei dati!

L'SQL mette a disposizione per la definizione dei dati, quindi per la definizione dello schema della base di dati, ovvero per la creazione delle nostre relazioni che potremmo ormai chiamare tabelle, in particolare l'istruzione CREATE TABLE. Quest'istruzione ha una sintassi simile a questa:

Codice:
CREATE TABLE nomeTabella (
  NomeCampo TipoCampo(dim) [,*]);

In particolare e' necessario scrivere CREATE TABLE, poi indicare il nome della tabella e tra parentesi (tonde) definire la definizione dei campi. Per ogni campo viene inserito il nome del campo (ovvero l'attributo) ed il tipo dell'attributo con relativa dimensione. Le parentesi quadre contenute nella sintassi dell'istruzione indicano elementi opzionali, per cui, se una tabella e' definita da piu' campi, quest'ultimi, dovranno essere separati da una virgola.

L'SQL NON E' case sensitive, quindi non fa distinzione fra maiuscole e minuscole, quindi CREATE TABLE, volendo, potremmo anche scriverlo in minuscolo, ma convenzionalmente le "parole chiave" sono indicate tutte maiuscole. Nel codice sottostante possiamo vedere un esempio in cui andiamo a creare una tabella "Libri".

Codice:
CREATE TABLE Libri (
    CodLibro CHAR(10) PRIMARY KEY,
    Titolo CHAR(60) NOT NULL,
    Genere CHAR(25) NOT NULL,
    Prezzo DOUBLE DEFAULT 0,
    Autore NUMERIC(10),
    FOREIGN KEY(Autore) REFERENCES
       Autori(codAutore)
);

Scriviamo quindi l'istruzione CREATE TABLE, seguito dal nome della tabella, nel nostro caso "Libri", per poi tra parentesi includere la sequenza dei campi.
In particolare viene creato:

- CodLibro - che e' di tipo carattere (10) ed e' specificato come PRIMARY KEY. In particolare quindi se un campo e' definito chiave primaria di una tabella, cio' deve essere indicato esplicitamente scrivendo PRIMARY KEY nella definizione del campo.

- Titolo - in questo caso e' carattere con dimensione 60, ed in questo caso per Titolo e' specificato NOT NULL, ovvero, il dbms non deve accettare record all'interno dei quali Titolo venga lasciato NULL, quindi non viene valorizzato.

- Genere - (anche in questo caso abbiamo NOT NULL)

- Prezzo - in questo caso abbiamo un DOUBLE non specificato come NOT NULL ma come DEFAULT(0), ovvero nel momento in cui l'operatore non inserisce alcun valore, allora automaticamente il prezzo verra' valorizzato a 0.

Autore - in questo caso il campo e' di tipo NUMERIC(10). Non stupisce, in quanto dovremmo aspettarcelo stringa (carattere), ma in questo caso autore crea la correlazione con la tabella autori, sostanzialmente e' numerico poiche' fa riferimento al codice autore, in pratica l'attributo RefAut di cui abbiamo scritto nella guida sull'algebra relazionale (ricordate..? se cosi' non fosse v'invito a leggervela.. la trovate al solito posto, sezione manuali di informatica quindi), solo che qui l'abbiamo chiamato autore! Ma questa cosa e' specificata nella riga successiva, dove scriviamo FOREIGN KEY(Autore), dove indichiamo che autore e' una chiave esterna e fa riferimento alla tabella Autori ed in particolare appunto all'attributo codAutore. Sostanzialmente questa scrittura equivale ad impostare un vincolo di integrita' referenziale ecco!

Concludiamo con la definizione della tabella con la parentesi tonda ovviamente.
Abbiamo definito quindi la tabella libri, stessa cosa per definire la tabella autori, con CREATE TABLE autori, metteremo quindi un CodAutore di tipo NUMERIC(10) e chiaramente indicheremo CodAutore come PRIMARY KEY e poi il nome dell'autore, nazionalita' e tutti i campi che vogliamo !

CREATE TABLE e' l'istruzione piu' importante per la definizione del nostro schema, ma sullo schema di una base dati e' possibile fare altre operazioni, una volta create le tabelle e' necessario anche in qualche modo modificare.. ci deve essere la possibilita' di modificare uno schema gia' creato, ecco, questo avviene con altre istruzioni di cui faremo comunque solo un accenno, altrimenti veramente non finiamo piu' raga!

Diciamo intanto che comunque per i singoli campi, alcuni dei domini possibili (dipende anche dalle varie implementazioni di SQL, ed ogni implementazione fornisce domini "particolari"), in linea di massima, sono:

- CHAR /* un qualsiasi attributo puo' essere di tipo carattere) */
- VARCHAR /* carattere variabile, in cui la dimensione magari non e' definita all'inizio */
- INTEGER
- SMALLINT
- FLOAT
- DOUBLE
- DATE
- TIMESTAMP
- *

Sono tutti i domini cui possono afferire gli attributi, i campi quindi!

Abbiamo poi i vincoli intra relazionali:

- NOT NULL
- PRIMARY KEY()

Entrambi li abbiamo gia' visti ma possiamo aggiungerne anche un altro:

- UNIQUE()

In questo caso, in pratica (come anche PRIMARY KEY()) potrebbe essere costituito da piu' attributi, in questo caso quest'ultimi andrebbero inseriti fra parentesi tonda. UNIQUE indica che quell'insieme di campi (fra tonde), non possono essere duplicati all'interno della base dati, sono unici e quindi a loro volta sono della altre chiavi.

I vincoli inter relazionali (cioe' tra piu' tabelle) sono espressi da:

- REFERENCES
- FOREIGN KEY

Che abbiamo gia' incontrato comunque, specificando il vincolo di integrita' relazionale tra l'attributo Autore della tabella Libri, con l'attributo CodAutore della tabella Autori.

Il CREATE TABLE serve quindi per creare i vari schemi delle tabelle (ovvero elle relazioni), ma ci sono altri "comandi" che consentono di modificare lo schema esistente:

- ALTER TABLE /* che permette di effettuare modifiche su tabelle create */
- ALTER DOMAIN
- DROP TABLE /* che cancella una tabella creata, non cancella i dati ma cancella la tabella */
- DROP DOMAIN /* che mi permette di cancellare un dominio creato con CREATE DOMAIN (di cui comunque volutamente non abbiamo scritto) */

Bon, con questo accenno alle varie istruzioni alle modifiche dei dati abbiamo chiuso il quadro relativo alla sezione del linguaggio SQL riferito esclusivamente alle istruzioni per la DEFINIZIONE dei dati. Dobbiamo adesso vedere invece le istruzioni (almeno le principali) per la manipolazione dei dati, ci concentreremo sopratutto sull'aspetto di INTERROGAZIONE, al termine poi accenneremo a qualche altra istruzione per l'AGGIORNAMENTO dei dati.. pero' senz'altro l'aspetto di interrogazione e' quello che ci interessa maggiormente.

Passiamo subito a vedere quindi la sezione delle istruzioni contenute nella parte relativa alla manipolazione dei dati, dove per manipolazione dei dati intendiamo interrogazione ed aggiornamento, l'SQL ha quindi delle istruzioni per l'aggiornamento ed una in particolare per l'interrogazione.
Per quanto concerne l'aggiornamento vedremo verso la fine di questa guida, le istruzioni:

- INSERT
- UPDATE
- DELETE

Ma nel frattempo ci concentriamo sull'istruzione piu' importante, che e' la SELECT, che serve per estrarre i dati ed interrogare la nostra base di dati, andando quindi ad estrarre i dati dalle nostre tabelle!

Presentiamo la nostra istruzione SELECT con degli esempi, come al solito, facendo riferimento ad una base di dati concreta, costituita soltanto da due tabelle: Libri e Autori, in realta' inizialmente la seconda non sara' considerata, ci concentreremo ed estrarremo i dati solo ed esclusivamente dalla tabella libri:

2vl8rxw.png


Dall'immagine sopra possiamo vedere la sintassi della SELECT, vediamo che abbiamo delle sezioni opzionali, in particolare riguardano la clausola WHERE (che potrebbe non esserci, ma e' molto raro che non ci sia) e la ORDER By, che serve per ordinare i risultati ottenuti.

La parte obbligatoria e' invece costituita dalla parola chiave SELECT seguita dall'elenco dei campi e dall'elenco delle tabella da cui estrarre i campi (preceduta quindi dalla parola FROM).

Vediamo subito un esempio: in particolare immaginiamo di voler interrogare la nostra base di dati estraendo dalla tabella libri soltanto l'attributo genere, vogliamo quindi conoscere il genere dei libri contenuti all'interno della tabella, sostanzialmente effettuiamo una proiezione sulla tabella estraendo quindi soltanto l'attributo genere, ecco il risultato:

208fole.png


L'istruzione SQL e' quindi SELECT genere FROM Libri
In questo caso l'elenco campi e' costituito dal solo campo genere e l'elenco tabelle contiene solo la tabella libri.

Il risultato e' quindi una tabella (vedere immaginetta sopra - a destra dell'istruzione SELECT).
Sono sicuro che qualcuno, che stia leggendo questa guida, si sara' accorto che nelle righe ci sono una serie di ripetizioni.. ecco, questo avviene perche' il risultato della SELECT non e' una relazione, bensi' una tabella, a differenza dell'algebra relazionale in cui gli operatori lavoravano su relazioni e restituivano relazioni, in questo caso quindi il risultato e' una tabella e sappiamo che una tabella non e' necessariamente una relazione e, affinche' possa essere considerata tale, non deve assolutamente avere righe ripetute/duplicate e per cui questa non puo' essere considerata una relazione.

Per ottenerne una e' necessario impostare la SELECT in maniera un po' diversa, ed e' necessario infatti aggiungere DISTINCT dopo SELECT, vediamolo:

rt3l34.png


Il risultato dell'istruzione SQL sara' appunto quello che ci aspettavamo, quindi una nuova tabella (che e' anche una relazione infatti), in cui ogni riga rappresenta il genere contenuto all'interno della tabella libri, di fatto a noi interessa anche a livello pratico che l'indicazione sia contenuta una volta soltanto e, attraverso questa interrogazione, sappiamo quindi che i libri contenuti all'interno della tabella possono essere di tipo novelle, saggio o romanzo!

Vediamo un altro esempio che ci richiede di utilizzare la clausola WHERE.
2d6v91h.png


Immaginiamo di voler ad esempio titolo e genere (della tabella libri) che costano meno di 15,00 (supponiamo euro).
In questo caso questa relazione con l'algebra relazionale potremmo esprimerla utilizzando l'operatore di selezione sulla tabella libri impostando come condizione che il prezzo sia minore di 15,00, questa produce una relazione in cui vengono escluse le righe che hanno un prezzo maggiore di 15 per poi, dal risultato finale, estrarre solo gli attributi titolo e genere.
In pratica abbiamo aggiunto alla nostra istruzione SQL la clausola WHERE! (abbiamo espresso volutamente le due istruzioni sia in algebra relazionale sia in SQL per fare un attimo un confronto/ripasso con quello che abbiamo visto nella precedente guida).

Ovviamente, all'interno della clausola WHERE, la condizione in realta' e' una espressione condizionale, ovvero e' possibile usare i vari operatori AND, OR, NOT e cosi' via.

Anyway, continuiamo con una nuova interrogazione che ci permette di introdurre un aspetto importante dell'istruzione SELECT, anticipiamo che all'interno della target list sara' possibile aggiungere delle espressioni, vediamo come:
14cf95z.png


In pratica, l'interrogazione che vogliamo risolvere e' l'estrazione del titolo e del prezzo scontato di 2(euro) dei libri, il cui genere e' saggio, ordinati rispetto al prezzo decrescente! Quindi, quest'interrogazione ci chiede di aggiungere due nuovi elementi alle informazioni che gia' conosciamo, in particolare il primo e' la possibilita', come dicevamo prima, di usare un'espressione all'interno della target list, quest'ultima vediamo che c'e' il titolo e c'e' anche il prezzo -2, quest'espressione e' essenzialmente algebrica, estraiamo il prezzo e tiriam via 2. Quest'attributo in realta' non ha nome, ma viene assegnato grazie all'operatore AS (che corrisponde all'operatore ridenominazione), in pratica quindi nella tabella finale, prezzo-2 ha come nome PrezzoScontato!
Abbiamo anche introdotto la clausola ORDER By che mi permette di ordinare il risultato della nostra istruzione SQL. L'ordinamento avviene rispetto ad un elenco di campi, in questo caso non c'e' un elenco ma c'e' soltanto un campo PrezzoScontato, ma se ci fossero piu' campi, questi dovrebbero essere separati da virgola, per esempio possiamo considerare un ordinamento di Cognome/Nome, l'ordinamento avviene prima rispetto al cognome e nel caso in cui si presentassero due cognomi uguali allora si procederebbe con l'ordinamento anche rispetto al nome!

L'orinamento puo' essere discendente o ascendente, in questo caso abbiamo impostato discendente ed essendo un campo di tipo numero l'ordinamento avviene dal piu' grande al piu' piccolo, l'ascendente e' ovviamente l'opposto! Nel caso avessimo avuto un ordinamento rispetto ad un attributo di tipo carattere, l'ordinamento avverrebbe in senso alfabetico ovviamente, per cui ascendente dalla A alla Z, discendente dalla Z alla A.

Continuiamo i nostri esempi introducendo un nuovo operatore che non abbiamo visto nell'algebra relazionale ma che pero' ci permette di effettuare estrazioni interessanti lavorando sulle stringhe di carattere, l'operatore e' LIKE e viene inserito all'interno delle espressioni condizionali contenute nella clausola WHERE

345g2vc.png


Tutti gli attributi della relazioni libri (nella target list vengono inseriti l'elenco degli attributi che si vogliono estrarre (proiezione). Ma quando questa coincide con l'intero elenco degli attributi non e' necessario ripetere ogni singolo attributo ma e' sufficente inserire un simbolo, lo star "*", che indica proprio "prendimi tutti gli attributi della relazione") per i quali l'attributo titolo (quindi dobbiamo usare un WHERE titolo) inizia con "U" ed il terzo carattere e' uno spazio (quindi in questo caso non c'e' una condizione di uguaglianza ma questo tipo di condizione va espressa con l'operatore LIKE).

L'operatore mi permette quindi di estrarre tutti i titoli che iniziano per U, come terzo carattere hanno lo spazio, il secondo carattere puo' essere qualslasi (cio' e' espresso dall'underscore (_)), e i caratteri successi allo spazio saranno in una combinazione qualsiasi (e questo e' espresso con un carattere "jolly" che e' la %).

Il risultato sara' quello visualizzato nell'immaginetta sopra!

Nella tabella che abbiamo utilizzato tutti gli attributi sono valorizzati, ma abbiamo visto che all'interno della tabella potrebbero esistere dei record che contengano dei campi nulli, che sono valorizzati con il valore NULL, modifichiamo quindi leggermente la tabella libri e immaginiamo per "Se una notte d'inverno un viaggiatore" il prezzo non sia definito/conosciuto, magari non e' stato ancora assegnato ed ha un valore NULL.
xmu5pt.png


L'istruzione SELECT ci permette di effettuare ricerche anche su valori NULL, immaginiamo ad esempio di volere tutti i libri di cui non si conosce ancora il prezzo, ecco, questo nell'SQL si esprime indicando SELECT* FROM libri WHERE prezzo IS NULL;

IS NULL indica proprio il cui valore e' NULL.
Se desiderassimo conoscere invece avere tutti i libri di cui si conosce il prezzo dovremmo utilizzare IS NOT NULL.
Bon, questa e' pero' ancora un'istruzione SQL che lavora su una sola tabella, ma e' naturalmente interessante riuscire ad estrarre dati fra piu' tabelle tra loro logicamente correlate e, abbiamo visto all'inizio che nella clausola della SELECT (in particolare dopo FROM) viene indicato l'elenco delle tabelle, fin ora l'elenco era costituito solo dalla tabella libri ma in realta' prendiamo adesso in considerazione la possibilita' di estrarre dati da piu' tabelle, effettueremo quindi un JOIN!

Allora potremmo desiderare ad esempio, come interrogazione, titolo, autore e prezzo dei romanzi.

adc1gy.png


Come possiamo riuscire risalire all'autore di ciascun titolo? Ora un attimo di attenzione in piu' eh.. naturalmente RefAut corrisponde a CodAutore nella tabella Autori, esiste quindi un vincolo di integrita' referenziale e l'espressione della nostra istruzione SQL SELECT sara' SELECT l.titolo (dove l e' sostanzialmente una variabile.. il valore viene assegnato attraverso FROM libri.l, quando noi diamo un qualsiasi carattere/insieme di caratteri, la l indica che titolo e' un attributo della tabella libri, questa modalita' di scrittura e' molto comoda quando il nome degli attributi e' identico in entrambe le tabelle, in questo caso potrebbe essere superfluo ma c'e' per uniformita' di scrittura, quindi l.titolo, a.autore (autore viene estratto dalla tabella a ovvero da autori), l.prezzo! FROM libri.l, autori.a, ecco che in questo caso il FROM ci permette di effettuare il JOIN! WHERE l.RefAut = a.codAutore; se non avessimo inserito la clausola WHERE avremmo avuto un inutile prodotto cartesiano ovviamente.. abbiamo gia' visto in algebra relazionale questo risultato e l'abbiamo espresso come un JOIN fra libro e autori su cui viene effettuata una selezione per la quale sara' impostata come condizione RefAut = codAut, quindi non e' altro che un theta join, che abbiamo espresso in questo modo (vedere immaginetta sopra) per essere piu' fedeli all'istruzione SQL, ed infine abbiamo una proiezione che estrae titolo, autore e prezzo!

Non c'e' stata necessita' di ridenominare e le due istruzioni (la prima in linguaggio SQL e la seconda in algebra relazionale) sono identiche e restituiscono lo stesso risultato!
Avremo quindi un JOIN fra le due tabelle e naturalmente mantenendo soltanto le righe per le quali RefAut e' uguale a CodAut.

Sempre parlando di JOIN facciamo un altro esempio, un po' piu' complesso, in quanto non vogliamo solo titolo, autore e prezzo, ma li vogliamo dei romanzi!
Quindi significa avere le prime due righe identiche all'istruzione precedente ma nella clausola WHERE oltre all'espressione che ci permette di effettuare il tetha join (l.RefAut = a.codAutore) aggiungiamo un AND genere='Romanzo'.

In algebra relazionale questo l'abbiamo espresso, se vi ricordate, come Libri JOIN Autori RefAut=codAut And genere='Romanzo', poi la proiezione e' identica, ma vediamo di cosa stiamo parlando!

210hmkx.png

Abbiamo estratto titolo, autore e prezzo unendo in maniera corretta gli attributi delle due tabelle estraendo quindi le righe che ci aspettavamo e abbiamo ulteriormente filtrato aggiungendo come condizione che il genere fosse Romanzo.
Quindi dal risultato finale precedente (senza l'AND) sono stati eliminati "Un ultimo giro di giostra" che e' un saggio, "Un indovino mi disse" idem e "Marcovaldo" (novelle)!

Bon, possiamo andare avanti scrivendo di JOIN esplicito (che stress .-. LOL non avete idea di quanto sia palloso fare tabelle e immaginette *gh*).
Abbiamo, in algebra relazionale, scritto di JOIN esterno (outer join: left, right e full) ricordate? Ecco, non e' detto che esista la possibilita' di effettuare tutte e tre le tipologie di JOIN (generalmente left e right ma non e' detto che esista il full).
30kt2qh.png


JOIN puo' essere espresso in maniera esplicita, ovvero non utilizzando nella claosula WHERE la condizione che ci permette di legare in maniera logica gli attributi fra loro correlati, ma puo' essere espresso inserendo dopo FROM, JOIN autori a ON (cioe' su) l.RefAut uguale ad a.codAutore, poi naturalmente aggiungiamo la clausola che mi permette di selezionare le righe in cui genere='Romanzo', in questo modo il JOIN viene esplicitato e la condizione di selezione, intesa come algebra relazionale, viene slegata dalla condizione di theta join! Il risultato ovviamente non cambia (vedere immaginetta sopra) e contiene tutte le righe della tabella da cui sono state naturalmente eliminate novelle e saggi.

Complichiamoci adesso un po' la vita (*gh*) osservando che le SELECT possono essere nidificate! Vediamo subito un esempio:

n41fr.png


Interroghiamo la nostra base di dati individuando il titolo e il prezzo dei romanzi di Tolstoj.
Vediamo subito che titolo e prezzo sono due campi contenuti nella tabella titolo, mentre invece Tolstoj che e' il nome dell'autore e' contenuto della tabella autore (terzultima riga vedi immaginetta). E' evidente che tra libri e autori esiste una correlazione ed e' fornita dall'attributo RefAut e da CodAutore (della tabella autori). In sostanza RefAut corrisponde di fatto a CodAutore della tabella autori, per cui prima di tutto bisognerebbe conoscere il codice dell'autore di Tolstoj, ma questo lo possiamo ottenere soltanto interrogando la tabella Autori e allora questo lo si puo' esprimere come l'istruzione dell'immagine.

Vediamo la SELECT piu' intena:

Estraiamo il codice dell'autore, FROM tabella autori, WHERE il nome dell'autore e' uguale al Tolstoj!
Se risolviamo la SELECT vediamo che Tolstoj e' unico (non ripetuto all'interno della tabella autori) e corrisponde il codice autore A06.
Quest'ultimo puo' essere sostituito al risultato della query! E' evidente che in questo caso il risultato e' unico ma una SELECT potrebbe restituire come risultato una serie di elementi e, in tal caso, un'espressione di questo tipo in cui abbiamo utilizzato l'operatore = sarebbe errata, perche' un valore non puo' essere = ad un insieme di valori, pero' in alcuni casi puo' essere utile verificare se un valore e' contenuto in un insieme di valori e in questo caso = andrebbe sostituito con IN (o verificarne l'assenza) con NOT IN.
Nell'esempio comunque il risultato e' unico (sta restituendo una chiave (PRIMARY KEY) quindi l'= e' corretto e valido!
Una volta risolta la query piu' interna (ottenuto A06) possiamo eseguire la query piu' esterna, quindi si estrae il titolo e prezzo FROM libri WHERE genere='Romanzo' (volevamo solo i romanzi di Tolstoj eh :p) AND RefAut = A06 (poiche' il risultato della query e' quello : >).

Le query nidificate ovviamente possono essere sostituite con altre tipologie di query, pero' bisogna dire che questa forma e' molto chiara e facilita la scrittura (si va per step ed e' tutto piu' ordinato quindi).

Ora, completiamo il discorso relativo alla SELECT, scrivendo degli operatori aggregati. Quest'ultimi sono degli operatori che ci permettono di estrarre dei risultati effettuando dei calcoli e in particolare elenchiamo:

- Count
- AVG
- SUM
- MAX
- MIN

Quindi conteggio, media, somma, massimo e minimo.
Per comprenderne l'uso, come al solito, proviamo a fare un paio d'esempi (e quindi ancora immagini e tabelle LOL siii lo so che vi piacciono tanto *,*).

Proviamo intanto a cercare il numero di romanzi contenuti nella tabella:
34t1vcx.png

Dobbiamo quindi contare il numero di volte in cui appare come valore Romanzo nel campo Genere, ovvero bisogna contare il numero di righe per le quali Genere=Romanzo, allora per estrarre solo i romanzi scriviamo una query in cui abbiamo una clausola del tipo WHERE genere='Romanzo', contiamo le righe con Count(*) (che mi conta il numero di righe all'interno del risultato ottenuto!). Al risultato attribuiamo con l'operatore AS il nome (ridenominiamo) totRomanzi, per cui, in definitiva, il risultato sara' una tabella costituita da una sola riga all'interno della quale ci sara' l'attributo totRomanzi e il valore 8 (se contiamo i romanzi infatti sono 8).

Il secondo esempio e' invece piu' particolare, potremmo infatti non voler conoscere il numero dei romanzi, ma vorremmo conoscere il numero di saggi, novelle e cosi' via e questo potremmo ottenerlo effettuando ripetutamente la stessa ricerca cambiando in WHERE il genere (ovviamente :D), tuttavia questa roba potrebbe essere ottenuta utilizzando la clausola GROUP By all'interno della select! (vedere seconda parte dell'immaginetta sopra).

Il risultato sara' quindi: novelle 1, saggio 2, romanzo 8.

Avremmo potuto ad esempio ordinare per genere, c'e' un totRomanzi che sarebbe stato meglio sostituire con totLibri (ma devo rifare l'immagine crist* e non ho voglia perche' non ho salvato il progetto (*gh*), avete capito comunque eh).

Con gli operatori aggregati si chiude l'aspetto legato all'SQL relativo all'interrogazione dei dati, facciamo ora, come promesso all'inizio, un cenno alle altre istruzioni, in particolare L'unione, che mi permette di estrarre i dati da piu' tabelle unendole, ovviamente in questo caso abbiamo visto che l'unione lavora solo su relazioni definite sugli stessi attributi, per cui dobbiamo necessariamente avere due tabelle definite sugli stessi attributi o prendere degli attributi unificabili.

33feya8.png


Non e' necessario che gli attributi abbiano lo stesso nome (in SQL), per l'algebra relazionare questo era invece fondamentale per la formalizzazione dell'istruzione stessa!
Nell'immaginetta possiamo comunque notare le sintassi che penso sia abbastanza chiara (in cui uniamo le tabelle).

Procediamo con le operazioni di aggiornamento (solo dei cenni anche in questo caso ovviamente eh), abbiamo:

- Inserimento
- Modifica
- Eliminazione

209rsx4.png

INSERT INTO (operazione di inserimento (guardare immagine per sintassi))
La sintassi e' INSERT INTO + tabella + eventuali elenco di attributi + values, ovvero l'elenco dei valori separati da virgole, all'interno della tabella, le righe possono essere inserite estraendo i dati attraverso una SELECT, quindi INSERT INTO tabella attributi SELECT..
I risultati di una SELECT potrebbero essere un insieme di righe (non piu' una sola riga) che vengono aggiunte all'interno della tabella in cui vogliamo inserire i dati. Nell'esempio stiamo inserendo all'interno della tabella classici una riga che e' costituita da Candido, Romanzo e Voltaire e l'inserimento e' di tipo posizionale quindi (Titolo - Genere - Autore).

Un'altra istruzione per l'aggiornamento dei dati e' DELETE, espresso come: DELETE FROM tabella + clausola WHERE (opzionale).
ATTENZIONE: Se non si esprime la clausola WHERE vengono cancellati tutti i dati della tabella, per cui DELETE FROM tabella equivale a svuotare appunto la tabella, DELETE FROM tabella + WHERE condizione ci eliminera' solo le righe che soddisfano la condizione data! Nell'esempio vogliamo eliminare dalla tabella successi la riga in cui l'autore e' uguale a Mazzantini.

Ultima sintassi e' l'istruzione di modifica, che ci permette di aggiornare una singola tabella.
UPDATE tabella + SET attributo = inseriamo <espressione | SELECT.. |NULL | DEFAULT (elenco di attributi)> + clausola WHERE (opzionale che se manca allora consentira' la modifica di TUTTE le righe presenti all'interno della tabella) che se presente, prevedera' la modifica soltanto delle righe che soddisfano la data condizione. Se volessimo, ad esempio, aumentare del 10% il prezzo di tutti i libri (indistintamente) ometteremo la clausola WHERE e faremo in modo che come attributo ci sia un'espressione che permettera' di aumentare il valore del prezzo gia' esistente!
Se per qualche motivo, invece, soltanto i libri di, non so' uno a caso, Dostoevskij, allora dovremmo specificare all'interno della clausola WHERE che autore=Dostoevskij, in realta' se facciamo riferimento alla tabella libri precedenti e' chiaro che non c'e' il nome dell'autore ma abbiamo comunque gia' visto come poter risolvere il problema !

SIGNORIII ce l'abbiamo fatta.. LOL .. con quest'ultime righe abbiamo completato l'intera serie di guide di base di dati! Io vi ringrazio (per chi abbia letto o leggera' le mie boiate).. che altro dire boh, non credevo che sarei riuscito a completare tutto sto macello in quanto, come avete visto, ci sono duemila grafici e immaginette che non pensavo di riuscire a realizzare in un tempo finito.. ahaha, ce l'ho fatta comunque *,* (con 4/5 ore in media a guida *gh*) pero' vabeh, e' stato e sara' sempre un piacere aiutare la community di inforge e contribuire ad aumentare la conoscenza di ogni singolo argomento!

Che dire, penso che per almeno una settimana faro' uno stop per riprendermi dallo shock subito da sistemi operativi + basi di dati (praticamente uno dopo l'altro).. per poi scegliere un nuovo argomentone di cui trattare.. non so ancora con certezza cosa fare anche se ho gia' qualche idea in mente che pero' non voglio spoilerare, o come ca**o dite qua voi game_hacari :-D

Bon, ci vediamo presto con una nuova serie..

PS: scusate come al solito se trovate qualche errore di battitura ma oggi poi era particolarmente lunga come cosa, quindi non ho riletto tutto per bene, rido' un'altra "passata" fra qualche giorno comunque per correggere qualche piccola eventuale imperfezione!

STAY TUNED!

Ciao, ciao o/

- http://www.inforge.net/community/ma...65181-guida-introduciamo-le-basi-di-dati.html
- http://www.inforge.net/community/ma...uida-basi-di-dati-il-modello-relazionale.html
- http://www.inforge.net/community/ma...5478-guida-basi-di-dati-la-progettazione.html
- http://www.inforge.net/community/ma...asi-di-dati-la-progettazione-concettuale.html
- http://www.inforge.net/community/ma...ida-basi-di-dati-la-progettazione-logica.html
- http://www.inforge.net/community/ma...guida-basi-di-dati-l-algebra-relazionale.html
- http://www.inforge.net/community/manuali-di-informatica/367480-guida-basi-di-dati-sql.html
 
Stato
Discussione chiusa ad ulteriori risposte.