Oracle: cosa fa `(+)` in una clausola WHERE?

Abbiamo trovato quanto segue in un’applicazione basata su Oracle che stiamo migrando (generalizzata) :

SELECT Table1.Category1, Table1.Category2, count(*) as Total, count(Tab2.Stat) AS Stat FROM Table1, Table2 WHERE (Table1.PrimaryKey = Table2.ForeignKey(+)) GROUP BY Table1.Category1, Table1.Category2 

Cosa fa (+) in una clausola WHERE? Non l’ho mai visto usato così prima.

A seconda di quale lato del “=” il “(+) è attivo, esso indica un join LEFT OUTER o RIGHT OUTER (in questo caso è un join esterno sinistro). È una syntax Oracle vecchia che a volte viene preferita da chi l’ho imparato prima, dal momento che a loro piace questo rende il loro codice più breve.

Meglio non usarlo però, per leggerezza.

Come altri hanno affermato, la syntax (+) è obsoleta, la syntax proprietaria utilizzata da Oracle per anni per ottenere gli stessi risultati di un OUTER JOIN . Presumo che abbiano adottato la loro syntax proprietaria prima che SQL-92 decida sulla syntax standard.

La query equivalente a quella che hai mostrato, utilizzando la syntax SQL standard OUTER JOIN (che ora è supportata da tutte le principali implementazioni RDBMS) sarebbe la seguente:

 SELECT Table1.Category1, Table1.Category2, COUNT(*) AS Total, COUNT(Table2.Stat) AS Stat FROM Table1 LEFT OUTER JOIN Table2 ON (Table1.PrimaryKey = Table2.ForeignKey) GROUP BY Table1.Category1, Table1.Category2; 

Che significa:

  • Tutte le righe da Table1 sono incluse nel risultato della query.
  • Dove ci sono righe corrispondenti in Table2 , includi quelle righe (ripetendo il contenuto da Table1 se ci sono più righe corrispondenti in Table2 ).
  • Dove non ci sono righe corrispondenti in Table2 , utilizzare NULL per tutte le colonne di Table2 nel risultato della query.

È una notazione di join esterno sinistra non ANSI. A partire da Oracle9i, la confusione della syntax dell’unione esterna usando la notazione ‘(+)’ è stata sostituita dalla syntax di outer join ISO 99.