Operator Oracle „(+)”


155

Sprawdzam kilka starych instrukcji SQL w celu ich udokumentowania i prawdopodobnie ulepszenia.

DBMS to Oracle

Nie rozumiem stwierdzenia, które brzmiało tak:

select ...
from a,b
where a.id=b.id(+)

Jestem zdezorientowany co do (+)operatora i nie mogłem go znaleźć na żadnym forach ... (wyszukiwanie + w cudzysłowie też nie działało).

W każdym razie użyłem `` Explain Plan '' programu SQLDeveloper i otrzymałem wynik z informacją, że HASH JOIN, RIGHT OUTERitp.

Czy byłaby jakaś różnica, jeśli usunę (+)operator na końcu zapytania? Czy baza danych musi spełniać jakiś warunek (taki jak posiadanie pewnych indeksów itp.), Zanim (+)będzie można jej użyć? Byłoby bardzo pomocne, gdybyś mógł mi podać proste zrozumienie lub kilka dobrych linków, w których mogę o tym przeczytać.

Dzięki!


1
To nie jest operator. To tylko część składni, która wpływa na to, co robi JOIN.
philipxy

Odpowiedzi:


186

Jest to notacja specyficzna dla Oracle dla OUTER JOIN, ponieważ format ANSI-89 (używający przecinka w klauzuli FROM do oddzielenia odniesień do tabel) nie standaryzował złączeń OUTER.

Zapytanie zostanie przepisane w składni ANSI-92 jako:

   SELECT ...
     FROM a
LEFT JOIN b ON b.id = a.id

Ten link całkiem dobrze wyjaśnia różnicę między połączeniami JOIN .


Należy również zauważyć, że chociaż (+)prace, Oracle zaleca nie jest używany :

Oracle zaleca używanie składni FROMklauzuli OUTER JOINzamiast operatora łączenia Oracle. Zapytania o sprzężenie zewnętrzne, które używają operatora sprzężenia Oracle, (+)podlegają następującym regułom i ograniczeniom, które nie mają zastosowania do składni FROMklauzuli OUTER JOIN:


79
Dokładnie tak. Aby utrzymać (+) prosto w mojej głowie (lewa strona kontra prawa strona), lubię myśleć o (+) jako o „dodawaniu wartości NULL, jeśli nie znaleziono dopasowania”. Na przykład „a.id = b.id (+)” oznacza, że ​​b.id ma wartość NULL, jeśli nie ma dopasowania z a.id.
plaża

dzięki .. Myślę, że dodanie go w klauzuli z powinno dać ten sam wynik!
Kiran S,

Możesz chcieć mieć link w oficjalnej dokumentacji Oracle: docs.oracle.com/html/A95915_01/sqopr.htm
Vargan

27

Operator (+) wskazuje sprzężenie zewnętrzne. Oznacza to, że Oracle nadal zwraca rekordy z drugiej strony sprzężenia, nawet jeśli nie ma dopasowania. Na przykład, jeśli a i b to emp i dept i możesz mieć pracowników nieprzypisanych do działu, poniższa instrukcja zwróci szczegóły wszystkich pracowników, niezależnie od tego, czy zostali przypisani do działu.

select * from emp, dept where emp.dept_id=dept.dept_id(+)

Krótko mówiąc, usunięcie (+) może spowodować istotną różnicę, ale w zależności od danych możesz nie zauważyć przez chwilę!


25

W Oracle (+) oznacza „opcjonalną” tabelę w JOIN. W swoim zapytaniu

SELECT a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id=b.id(+)

jest to LEWE POŁĄCZENIE ZEWNĘTRZNE tabeli „b” do tabeli „a”. Zwróci wszystkie dane z tabeli „a” bez utraty danych, jeśli po drugiej stronie (opcjonalna tabela „b”) nie ma żadnych danych.

Schemat lewego zewnętrznego połączenia

Nowoczesna standardowa składnia dla tego samego zapytania byłaby

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
LEFT JOIN b ON a.id=b.id

lub ze skrótem dla a.id=b.id(nie obsługiwane przez wszystkie bazy danych):

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
LEFT JOIN b USING(id)

Jeśli usuniesz (+), będzie to normalne zapytanie sprzężenia wewnętrznego

Starsza składnia, zarówno w Oracle, jak i innych bazach danych:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id=b.id

Bardziej nowoczesna składnia:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
INNER JOIN b ON a.id=b.id

Lub po prostu:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
JOIN b ON a.id=b.id

Schemat połączenia wewnętrznego

Zwróci tylko wszystkie dane, w których wartość identyfikatora obu tabel „a” i „b” jest taka sama, czyli część wspólna.

Jeśli chcesz, aby twoje zapytanie było prawidłowe

To jest to samo, co LEFT JOIN, ale przełącza, która tabela jest opcjonalna.

Schemat prawego połączenia zewnętrznego

Stara składnia Oracle:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id(+)=b.id

Nowoczesna standardowa składnia:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
RIGHT JOIN b ON a.id=b.id

Odwołanie i pomoc:

https://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:6585774577187

Left Outer Join za pomocą + Zaloguj się w Oracle 11g

https://www.w3schools.com/sql/sql_join_left.asp


Etykiety kółek „tabela1” i „tabela2” są bezsensowne. Najprostszym znaczeniem elementów koła są wiersze wyjściowe. Następnie lewy półksiężyc zawiera przedłużone o zero wiersze tabeli tabela1, a prawy półksiężyc zawiera rozszerzone o zero wiersze tabeli tabela2. Inne znaczenia dla kręgów są niejasne. Jak myślisz, co dokładnie oznaczają te diagramy? Dlaczego umieściłeś je w innym miejscu niż ślepe kopiowanie (złych) prezentacji innych osób?
philipxy

Okręgi zostały oznaczone jako a i b. Okręgi nie są rzędami a i b. Kręgi lewy i prawy można rozsądnie nazwać rzędami lewego złącza b i prawego złącza b. Co więcej, nie opisujesz, czym są te otoczone wierszami pod względem danych wejściowych. Przekonaj się, jakie rzeczy są w kręgach. Jeśli zamierzasz przykleić etykiety a i b do kół, wyjaśnij jasno słowami, co każda etykieta ma wspólnego ze swoim okręgiem. (Nie ma prostego powodu, aby oznaczać je jako a i b). Dobrze, że prawidłowo oznaczyłeś zielone strefy.
philipxy

6

W praktyce symbol + jest umieszczany bezpośrednio w instrukcji warunkowej i po stronie opcjonalnej tabeli (takiej, która w warunku może zawierać wartości puste lub zerowe).


(+) Jest umieszczany bezpośrednio po prawej stronie nazwy kolumny. Ta odpowiedź nie jest co do tego jasna. Co ma znaczyć „w praktyce”? (Retorycznie) (I prawdopodobnie nie masz na myśli „oświadczenia”).
philipxy
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.