Lezione 3: Joins e Relazioni — Facciamo Parlare le Tue Tabelle!


Lesson3

Lezione 3: Joins e Relazioni — Facciamo Parlare le Tue Tabelle!

Bentornato, coraggioso cavaliere dei dati! Ora che sai come creare e gestire le tue tabelle, è giunto il momento di dare loro un po’ di vita sociale. Dopotutto, le basi di dati non dovrebbero starsene nei loro castelli, lanciandosi occhiate sospettose da dietro i muri. No, devono comunicare! Oggi esploreremo il mondo dei Joins e delle Relazioni — pensalo come un evento di speed dating per le tue tabelle, ma senza il rischio di domande scomode o di silenzi imbarazzanti.

Cos’è un Join?

In parole povere, un Join è un modo per dire a PostgreSQL: “Ehi, fai sedere queste due tabelle una accanto all’altra e falle chiacchierare!” I Joins ti permettono di combinare dati da due o più tabelle in base a una colonna in comune. Immagina di organizzare una cena dove ogni tavolo ha una lista di ospiti unica, ma tutti hanno qualcosa in comune (tipo l’amore per i ravioli fatti in casa).

Tipi di Join: Chi Chiacchiera con Chi?

Ci sono vari tipi di join, ciascuno con il proprio stile. Vediamo i più gettonati:

  1. INNER JOIN: “Incontriamoci solo se abbiamo qualcosa in comune.”
  2. LEFT JOIN: “Tutti dal tavolo A entrano e, se c’è posto, inviteremo qualcuno dal tavolo B.”
  3. RIGHT JOIN: L’opposto del LEFT JOIN — la priorità è per il tavolo B, e il tavolo A può unirsi se lo desidera.
  4. FULL OUTER JOIN: “Tutti sono i benvenuti!” (anche se non hanno portato il vino).

Vediamoli in azione!

1. INNER JOIN: Il Selettivo

L’INNER JOIN restituisce solo le righe che hanno valori corrispondenti in entrambe le tabelle. Immagina di avere una tabella cavalieri e una tabella missioni. La tabella cavalieri elenca tutti i cavalieri e la tabella missioni elenca le missioni a cui si sono iscritti:

CREATE TABLE cavalieri (
    id SERIAL PRIMARY KEY,
    nome VARCHAR(100),
    regno VARCHAR(50)
);

CREATE TABLE missioni (
    id SERIAL PRIMARY KEY,
    cavaliere_id INT,
    nome_missione VARCHAR(100)
);

Ora scopriamo quali cavalieri hanno accettato una missione:

SELECT cavalieri.nome, missioni.nome_missione
FROM cavalieri
INNER JOIN missioni
ON cavalieri.id = missioni.cavaliere_id;

Questo comando restituirà una lista di tutti i cavalieri che sono attualmente in missione. Se un cavaliere sta bighellonando a Camelot senza fare nulla, non lo vedrai qui. (Scusa Sir Lancillotto, trovati qualcosa di utile da fare!)

2. LEFT JOIN: L’Ospite Gentile

Il LEFT JOIN restituisce tutte le righe dalla tabella sinistra (in questo caso, cavalieri), e le righe corrispondenti dalla tabella destra (missioni). Se non c’è una corrispondenza, vedrai NULL per le colonne della tabella destra. È come invitare tutti dal cavalieri a una festa e poi controllare chi è davvero impegnato a fare qualcosa.

SELECT cavalieri.nome, missioni.nome_missione
FROM cavalieri
LEFT JOIN missioni
ON cavalieri.id = missioni.cavaliere_id;

Ora, anche se un cavaliere è semplicemente seduto a lucidare la sua armatura, apparirà nella lista — ma con NULL come missione. Un po’ di malinconia medievale, no?

3. RIGHT JOIN: Il Ribaltamento

Il RIGHT JOIN fa l’opposto: restituisce tutte le righe della tabella destra (missioni) e le righe corrispondenti dalla tabella sinistra (cavalieri). È come dire: “Quali missioni ci sono e chi si è preso la briga di iscriversi?”

SELECT cavalieri.nome, missioni.nome_missione
FROM cavalieri
RIGHT JOIN missioni
ON cavalieri.id = missioni.cavaliere_id;

Questo mostrerà tutte le missioni, anche se alcune di esse sono solo in attesa che un cavaliere coraggioso si faccia avanti.

4. FULL OUTER JOIN: L’Ingresso Libero

Il FULL OUTER JOIN restituisce tutte le righe quando c’è una corrispondenza in entrambe le tabelle, sinistra o destra. Se non c’è corrispondenza, ottieni valori NULL. È l’unione del “più siamo, meglio è.”

SELECT cavalieri.nome, missioni.nome_missione
FROM cavalieri
FULL OUTER JOIN missioni
ON cavalieri.id = missioni.cavaliere_id;

Questo mostrerà tutti i cavalieri e tutte le missioni, indipendentemente dal fatto che abbiano qualcosa in comune. Pensalo come un mega-raduno di cavalieri e missioni.

Costruire Relazioni: Chiavi Primarie e Chiavi Esterne

Allora, come facciamo capire a PostgreSQL che cavaliere_id nella tabella missioni è collegato alla colonna id nella tabella cavalieri? È qui che entrano in gioco le relazioni.

  1. Chiave Primaria (Primary Key): È come la carta d’identità del cavaliere. Identifica in modo univoco ogni riga della tabella. Nel nostro esempio, cavalieri.id è una chiave primaria.
  2. Chiave Esterna (Foreign Key): È come il numero sul biglietto d’ingresso. Fa riferimento a una chiave primaria in un’altra tabella. Qui, missioni.cavaliere_id è una chiave esterna che rimanda a cavalieri.id.

Aggiungere un Vincolo di Chiave Esterna

Rendiamolo ufficiale aggiungendo un vincolo di chiave esterna alla nostra tabella missioni:

ALTER TABLE missioni
ADD CONSTRAINT fk_cavaliere
FOREIGN KEY (cavaliere_id)
REFERENCES cavalieri(id);

Ora PostgreSQL sa che missioni.cavaliere_id deve corrispondere a un cavalieri.id. Se provi a creare una missione per un cavaliere inesistente, PostgreSQL ti bloccherà più velocemente di un drago affamato.

Mettiamo Tutto Insieme: Un Mini Scenario

Ecco un piccolo script per mettere in pratica tutti questi joins:

CREATE TABLE cavalieri (
    id SERIAL PRIMARY KEY,
    nome VARCHAR(100),
    regno VARCHAR(50)
);

CREATE TABLE missioni (
    id SERIAL PRIMARY KEY,
    cavaliere_id INT,
    nome_missione VARCHAR(100),
    FOREIGN KEY (cavaliere_id) REFERENCES cavalieri(id)
);

INSERT INTO cavalieri (nome, regno)
VALUES ('Sir Lancillotto', 'Camelot'),
       ('Sir Galahad', 'Camelot'),
       ('Re Artù', 'Camelot');

INSERT INTO missioni (cavaliere_id, nome_missione)
VALUES (1, 'Cercare il Graal'),
       (2, 'Sconfiggere il Cavaliere Nero');

Provalo nel tuo terminale PostgreSQL e guarda la magia accadere!

Cosa Abbiamo Imparato Oggi?

Oggi abbiamo esplorato:

  • INNER JOIN: Restituisce solo le righe con valori corrispondenti.
  • LEFT JOIN: Restituisce tutte le righe della tabella sinistra e le corrispondenze dalla destra.
  • RIGHT JOIN: Restituisce tutte le righe della tabella destra e le corrispondenze dalla sinistra.
  • FULL OUTER JOIN: Tutti entrano, senza eccezioni!

Pronto per continuare? Vai alla Lezione 4: Query Annidate.


Benvenuto nel mondo delle relazioni tra tabelle. Che i tuoi join siano veloci e le tue tabelle non smettano mai di chiacchierare!