Oracle
 sql >> Database >  >> RDS >> Oracle

self join vs inner join

Trovo utile pensare a tutte le tabelle in un'istruzione SELECT come a rappresentare i propri set di dati.

Prima di aver applicato qualsiasi condizione, puoi pensare che ogni set di dati sia completo (l'intera tabella, ad esempio).

Un join è solo uno dei tanti modi per iniziare a perfezionare quei set di dati per trovare le informazioni che desideri davvero.

Sebbene uno schema di database possa essere progettato tenendo conto di determinate relazioni (Chiave primaria <-> Chiave esterna), queste relazioni esistono davvero solo nel contesto di una particolare query. Lo scrittore di query può mettere in relazione ciò che vuole con ciò che vuole. Ne farò un esempio più avanti...

Un INNER JOIN mette in relazione due tabelle tra loro. Spesso ci sono più operazioni JOIN in una query per concatenare più tabelle. Può diventare complicato quanto necessario. Per un semplice esempio, considera le seguenti tre tabelle...

STUDENT

| STUDENTID | LASTNAME | FIRSTNAME |
------------------------------------
      1     |  Smith   |   John
      2     |  Patel   |  Sanjay
      3     |   Lee    |  Kevin
      4     |  Jackson |  Steven
ENROLLMENT

| ENROLLMENT ID | STUDENTID | CLASSID |
---------------------------------------
        1       |     2     |    3
        2       |     3     |    1
        3       |     4     |    2
CLASS

| CLASSID | COURSE | PROFESSOR |
--------------------------------
     1    | CS 101 |   Smith
     2    | CS 201 |  Ghandi
     3    | CS 301 |  McDavid
     4    | CS 401 |  Martinez

La tabella STUDENT e la tabella CLASS sono state progettate per relazionarsi tra loro attraverso la tabella ISCRIZIONE. Questo tipo di tabella è chiamato Tabella di giunzione .

Per scrivere una query per visualizzare tutti gli studenti e le classi a cui sono iscritti si utilizzerebbe due giunzioni interne...

SELECT stud.LASTNAME, stud.FIRSTNAME, class.COURSE, class.PROFESSOR
FROM STUDENT stud
INNER JOIN ENROLLMENT enr
    ON stud.STUDENTID = enr.STUDENTID
INNER JOIN CLASS class
    ON class.CLASSID = enr.CLASSID;

Leggi attentamente quanto sopra e dovresti vedere cosa sta succedendo. Quello che otterrai in cambio è il seguente set di dati...

 | LASTNAME | FIRSTNAME | COURSE | PROFESSOR |
 ---------------------------------------------
     Patel  |   Sanjay  | CS 301 |  McDavid
      Lee   |   Kevin   | CS 101 |   Smith
    Jackson |  Steven   | CS 201 |  Ghandi

Utilizzando le clausole JOIN abbiamo limitato i set di dati di tutte e tre le tabelle solo a quelli che corrispondono tra loro. Le "corrispondenze" sono definite utilizzando ON clausole. Tieni presente che se avessi eseguito questa query non vedere la riga CLASSID 4 della tabella CLASS o la riga STUDENTID 1 della tabella STUDENT perché quegli ID non esistono nelle partite (in questo caso la tabella ISCRIZIONE). Esamina le JOIN "LEFT"/"RIGHT"/"FULL OUTER" per ulteriori informazioni su come farlo funzionare in modo leggermente diverso.

Tieni presente che, in base ai miei commenti precedenti sulle "relazioni", non vi è nessun motivo perché non è stato possibile eseguire una query relativa alla tabella STUDENT e alla tabella CLASS direttamente sulle colonne LASTNAME e PROFESSOR. Quelle due colonne corrispondono nel tipo di dati e, guardalo! Hanno anche un valore in comune! Questo sarebbe probabilmente uno strano set di dati da ottenere in cambio. Il punto è che può essere fatto e non sai mai quali esigenze potresti avere in futuro per connessioni interessanti nei tuoi dati. Comprendi il design del database, ma non pensare alle "relazioni" come regole che non possono essere ignorate.

Nel frattempo... SELF SI UNISCE!

Considera la seguente tabella...

PERSON

| PERSONID | FAMILYID |  NAME  |
--------------------------------
      1    |     1    |  John
      2    |     1    | Brynn
      3    |     2    | Arpan
      4    |     2    | Steve
      5    |     2    |  Tim
      6    |     3    | Becca

Se ti sentivi così propenso a creare un database di tutte le persone che conosci e quali sono della stessa famiglia, questo potrebbe essere quello che sembra.

Se volessi restituire una persona, PERSONA 4, per esempio, scriveresti...

SELECT * FROM PERSON WHERE PERSONID = 4;

Impareresti che è nella famiglia con FAMILYID 2. Quindi per trovare tutto delle PERSONE della sua famiglia scriveresti...

SELECT * FROM PERSON WHERE FAMILYID = 2;

Fatto e fatto! SQL, ovviamente, può farlo in una query usando, hai indovinato, un SELF JOIN.

Ciò che fa davvero scattare la necessità di un SELF JOIN ecco che la tabella contiene una colonna univoca (PERSONID) e una colonna che funge da sorta di "Categoria" (FAMILYID). Questo concetto è chiamato Cardinalità e in questo caso rappresenta un uno a molti o 1:M relazione. Ce n'è solo uno di ogni PERSONA ma ce ne sono molti PERSONE in una FAMIGLIA .

Quindi, quello che vogliamo restituire è tutto dei membri di una famiglia se uno si conosce il PERSONID della famiglia...

SELECT fam.*
FROM PERSON per
JOIN PERSON fam
    ON per.FamilyID = fam.FamilyID
WHERE per.PERSONID = 4;

Ecco cosa otterresti...

| PERSONID | FAMILYID |  NAME  |
--------------------------------
      3    |     2    | Arpan
      4    |     2    | Steve
      5    |     2    |  Tim

Notiamo un paio di cose. Le parole SI UNISCITI non si verificano da nessuna parte. Questo perché un SELF JOIN è solo un concetto La parola UNISCI nella query precedente potrebbe essere stato un LEFT JOIN invece e sarebbero successe cose diverse. Il punto di un SELF JOIN è che stai usando la stessa tabella due volte.

Considera la mia soapbox di prima sui set di dati. Qui abbiamo iniziato con il set di dati dalla tabella PERSON due volte. Né istanza del set di dati influisce sull'altro a meno che non lo diciamo noi.

Iniziamo dalla parte inferiore della query. Il per il set di dati è limitato solo a quelle righe in cui PERSONID =4. Conoscendo la tabella sappiamo che restituirà esattamente una riga. La colonna FAMILYID in quella riga ha un valore di 2.

Nella clausola ON limitiamo la fam set di dati (che a questo punto è ancora l'intera tabella PERSON) alle sole righe in cui il valore di FAMILYID corrisponde a uno o più dei FAMILYID del per set di dati. Come abbiamo discusso, conosciamo il per il set di dati ha solo una riga, quindi un valore FAMILYID. Pertanto la fam il set di dati ora contiene solo righe in cui FAMILYID =2.

Infine, nella parte superiore della query selezioniamo tutte le righe nella fam set di dati.

Ecco! Due query in una.

In conclusione, un INNER JOIN è uno dei diversi tipi di operazioni JOIN. Lo farei fortemente suggerisci di leggere ulteriormente le JOIN SINISTRA, DESTRA e FULL OUTER (che sono, collettivamente, chiamate OUTER JOIN ). Personalmente ho perso un'opportunità di lavoro per avere una conoscenza debole di OUTER JOIN una volta e non lascerò che accada di nuovo!

UN AUTO UNISCITI è semplicemente qualsiasi operazione JOIN in cui si correla una tabella a se stessa. Il modo in cui scegli di UNIRSI a quel tavolo può utilizzare un INNER JOIN o un OUTER JOIN. Tieni presente che con un SELF JOIN , per non confondere il tuo motore SQL devi usa gli alias di tabella (fam e per dall'alto. Crea qualsiasi cosa abbia senso per la tua query) o non c'è modo di differenziare le diverse versioni della stessa tabella.

Ora che capisci la differenza, apri la tua mente in modo chiaro e completo e renditi conto che una singola query potrebbe contenere tutti i diversi tipi di JOIN contemporaneamente. È solo una questione di quali dati vuoi e come devi distorcere e piegare la tua query per ottenerli. Se ti ritrovi a eseguire una query e prendere il risultato di quella query e utilizzarlo come input di un'altra query, probabilmente puoi utilizzare un JOIN per fare una query invece.

Per giocare con SQL, prova a visitare W3Schools.com C'è un database memorizzato localmente lì con un mucchio di tabelle progettate per relazionarsi tra loro in vari modi ed è pieno di dati! Puoi CREARE, RILASCIARE, INSERIRE, AGGIORNARE e SELEZIONARE tutto ciò che desideri e riportare il database alle impostazioni predefinite in qualsiasi momento. Prova tutti i tipi di SQL per sperimentare diversi trucchi. Ho imparato molto lì, io stesso.

Scusa se sono stato un po' prolisso, ma personalmente ho lottato con il concetto di JOIN quando stavo iniziando a imparare l'SQL e spiegare un concetto usando un sacco di altri concetti complessi mi ha impantanato. È meglio iniziare dal basso a volte.

Spero possa essere d'aiuto. Se riesci a mettere JOIN nella tua tasca posteriore puoi fare magie con SQL!

Buona interrogazione!