Questa è la natura di un join esterno (in questo caso un join sinistro). Un join di sinistra prende la tabella principale (Clienti), la confronta con i criteri nella tabella unita (Ordini). Per ogni riga in Clienti che non ha una corrispondenza, a differenza di un join interno, non rimuove la riga. Invece, aggiunge tutti i campi dagli ordini ma inserisce nulla in essi.
Guardate questo esempio:
Table A Table B
┌──────┬──────┐ ┌──────┬──────┐
│field1│field2│ │field3│field4│
├──────┼──────┤ ├──────┼──────┤
│A │1 │ │1 │One │
│B │2 │ │3 │Three │
│C │3 │ └──────┴──────┘
└──────┴──────┘
dei tavoli join interno (tra il campo2 e field3) è:
┌──────┬──────┬──────┬──────┐
│field1│field2│field3│field4│
├──────┼──────┤──────┼──────┤
│A │1 │1 │One │
│C │3 │3 │Three │
└──────┴──────┴──────┴──────┘
Ma le tabelle outer join deve dare ogni record, e se non vi è alcuna corrispondenza, inserire i null.
┌──────┬──────┬──────┬──────┐
│field1│field2│field3│field4│
├──────┼──────┤──────┼──────┤
│A │1 │1 │One │
│B │2 │NULL │NULL │⬅︎ No match
│C │3 │3 │Three │
└──────┴──────┴──────┴──────┘
Ora cosa succederebbe se non ci fossero corrispondenze in tabella2? Ad esempio, se hai aggiunto una condizione impossibile nella clausola ON? Poi tutti i record nel risultato sarà simile al "Nessuna corrispondenza"
┌──────┬──────┬──────┬──────┐
│field1│field2│field3│field4│
├──────┼──────┤──────┼──────┤
│A │1 │NULL │NULL │⬅︎ No match (because of impossible condition)
│B │2 │NULL │NULL │⬅︎ No match (because of impossible condition)
│C │3 │NULL │NULL │⬅︎ No match (because of impossible condition)
└──────┴──────┴──────┴──────┘
Quindi non importa se non ci fosse partita, perché non vi era alcuna traccia nel Table2 con il dato ID, o se non ci fosse corrisponde perché hai aggiunto una condizione impossibile. Il risultato di un join esterno è che i campi che dovevano provenire da Table2 sarebbero stati sostituiti con valori null. Perché è così che viene definito un join esterno.
Ora ai tavoli del mondo reale:
in realtà non hanno alcun record di ordini la cui IDOrdine è nullo (a meno che non avete progettato molto male). Quindi, se si inserisce questa condizione nella clausola ON, non troverà record che soddisfano i criteri.
In tal caso, poiché si tratta di un join esterno (a sinistra), si ottengono tutti i record dei clienti originali e, poiché non vi sono corrispondenze, ognuno di essi ha i campi da Ordini tutti nulli.
Nel caso in cui si inserisse la condizione nello WHERE
, si stava effettivamente sfruttando questo comportamento di un join sinistro. Hai abbinato ogni cliente con il suo ordine. Se c'era una corrispondenza - bene, hai l'ID ordine reale. Ma nei casi in cui non c'era corrispondenza - quelli che stai cercando - aggiunge un ID ordine nullo.
La clausola where indica quindi di fornire solo i record in cui è successo. Cioè, i record che non avevano un ordine corrispondente in Ordini.
Capisco intuitivamente perché lo pensereste, ma penso che la ragione sia che 'ON' è usato per unire le tabelle su una determinata condizione. Quello che stai cercando di fare è cercare le righe DOVE una condizione è vera. Non so se questo è vicino alla verità, ma è come sono arrivato a pensarci e sapere quando usare cosa. – AdamMc331
l'AND o.OrderID è quello che sta rovinando tutto. Funzionerebbe correttamente finché non colpisce la condizione AND .... – rvphx