Znajdujemy się w trzecim artykule z serii migracji Oracle. Tym razem przyjrzymy się tym dziwnym operatorom, które modyfikują kryteria klauzuli WHERE w Oracle (+). Jak wszystko inne, PostgreSQL ma na to rozwiązanie.
PRAWY DOŁĄCZ
Oracle obsługuje, a wielu programistów używa zewnętrznej składni ANSI JOIN, używając operatorów do klauzuli kwalifikacji.
Zazwyczaj wygląda to mniej więcej tak:
SELECT *
FROM person, places
WHERE person.id = places.person_id(+)
Celem tej składni jest prawe sprzężenie zewnętrzne. W kategoriach teorii mnogości jest to podzbiór obejmujący wszystkie miejsca, niezależnie od osoby.
Wynik małej próbki wyglądałby tak:
id | nazwisko | imię | id | lokalizacja | person_id |
---|---|---|---|---|---|
1 | (NULL) | (NULL) | 1 | Dallas | (NULL) |
2 | Roybal | Kirk | 2 | Londyn | 2 |
3 | Riggs | Simon | 3 | Paryż | 3 |
Ta składnia nie jest obsługiwana w PostgreSQL.
Aby osiągnąć ten sam wynik, użyjesz standardowej składni SQL dla złączeń zewnętrznych.
SELECT *
FROM persons
RIGHT JOIN places
ON persons.id = places.person_id;
SQL zawiera również wyjaśniający przysłówek OUTER
. Ten klaryfikator jest całkowicie opcjonalny, ponieważ każdy RIGHT JOIN
jest z definicji OUTER
dołącz.
Pełne dołączenie
Podobnie, użycie składni Oracle do pełnego dołączenia nie działa w PostgreSQL.
SELECT *
FROM persons, places
WHERE persons.id(+) = places(+);
Celem tej składni jest pełna lista osób i miejsc, niezależnie od tego, czy dana osoba jest powiązana z miejscem, czy nie.
Wynik wygląda tak:
id | nazwisko | imię** | id | lokalizacja | person_id |
---|---|---|---|---|---|
1 | (NULL) | (NULL) | 1 | Dallas | (NULL) |
2 | Roybal | Kirk | 2 | Londyn | 2 |
3 | Riggs | Simon | 3 | Paryż | 3 |
4 | Andrzej | Dunstan | (NULL) | (NULL) | (NULL) |
Używając składni PostgreSQL, zapytanie zostanie napisane w następujący sposób:
SELECT *
FROM persons
FULL JOIN places
ON persons.id = places.person_id;
Ponownie, OUTER
słowo kluczowe jest całkowicie opcjonalne.
POŁĄCZENIE KRZYŻOWE
Jedną z wyraźnych zalet podejścia do używania słów kluczowych zamiast niejawnych relacji jest to, że nie można przypadkowo utworzyć różnych produktów.
Składnia:
SELECT *
FROM persons
LEFT JOIN places;
Spowoduje błąd:
ERROR: syntax error at or near ";"
Wskazuje, że oświadczenie nie jest kompletne przy znaczniku końca wiersza „;”.
PostgreSQL utworzy produkt łączenia krzyżowego przy użyciu składni ANSI.
SELECT *
FROM persons, places;
id | nazwisko | imię | identyfikator | lokalizacja | identyfikator_osoby |
---|---|---|---|---|---|
1 | Dunstan | Andrzej | 1 | Dalle | (null) |
1 | Dunstan | Andrzej | 2 | Londyn | 2 |
1 | Dunstan | Andrzej | 3 | Paryż | 3 |
1 | Dunstan | Andrzej | 4 | Madryt | (null) |
2 | Roybal | Kirk | 1 | Dalle | (null) |
2 | Roybal | Kirk | 2 | Londyn | 2 |
2 | Roybal | Kirk | 3 | Paryż | 3 |
2 | Roybal | Kirk | 4 | Madryt | (null) |
3 | Riggs | Szymon | 1 | Dalle | (null) |
3 | Riggs | Szymon | 2 | Londyn | 2 |
3 | Riggs | Szymon | 3 | Paryż | 3 |
3 | Riggs | Szymon | 4 | Madryt | (null) |
6 | Wong | Zaznacz | 1 | Dalle | (null) |
6 | Wong | Zaznacz | 2 | Londyn | 2 |
6 | Wong | Zaznacz | 3 | Paryż | 3 |
6 | Wong | Zaznacz | 4 | Madryt | (null) |
Co jest bardziej prawdopodobnym błędem kodowania niż zamierzonym wynikiem.
Aby celowo uzyskać tę funkcjonalność, zaleca się użycie CROSS JOIN
oświadczenie.
SELECT *
FROM persons
CROSS JOIN places;
Dzięki temu jest jednoznaczne, co miało na myśli w oświadczeniu.
POŁĄCZENIE NATURALNE
PostgreSQL obsługuje NATURAL JOIN
składnia, ale nieco protestowana.
SELECT *
FROM persons
NATURAL JOIN places;
Daje to następujący wynik.
id | nazwisko | imię | identyfikator_rodzica | lokalizacja | identyfikator_osoby |
---|---|---|---|---|---|
1 | Dunstan | Andrzej | (null) | Dalle | (null) |
2 | Roybal | Kirk | 1 | Londyn | 2 |
3 | Riggs | Szymon | 1 | Paryż | 3 |
Jednak ta składnia jest problemem. W naszym przykładzie kolumna „id” w obu tabelach nie ma ze sobą nic wspólnego . To połączenie przyniosło wynik, ale z zupełnie nieistotną treścią.
Dodatkowo możesz mieć zapytanie, które początkowo przedstawia poprawny wynik, ale kolejne instrukcje DDL po cichu wpływają.
Rozważ:
ALTER TABLE person ADD COLUMN places_id bigint;
ALTER TABLE places ADD COLUMN places_id bigint;
ALTER TABLE person ADD COLUMN person_id bigint;
Jaka kolumna to NATURAL JOIN
za pomocą? Dostępne opcje to id, places_id, person_id i wszystkie powyższe. Zostawię odpowiedź jako ćwiczenie dla czytelnika.
Ta składnia to bomba zegarowa dla twojego kodu. Po prostu go nie używaj.
Ok, więc nie jesteś przekonany. Cóż, więc przynajmniej miej trochę rozsądnych konwencji kodowania. W przypadku tabeli nadrzędnej nazwij kolumnę tożsamości „myparenttable_id”. Odwołując się do niego z relacji podrzędnych, użyj tej samej nazwy, „myparenttable_id”. Nigdy nie nazywaj niczego „id” i nigdy nie odnoś się do kolumny o innej nazwie. Ach, zapomnij. Po prostu tego nie rób.
Możesz ulec pokusie, aby ujednoznacznić poprzednią zagadkę za pomocą USING
słowo kluczowe. To wyglądałoby tak:
SELECT *
FROM persons
JOIN places
USING (id);
Ale USING
słowo kluczowe może korzystać tylko z dokładnych dopasowań nazw w tabelach. Co znowu, w naszym przykładzie, jest po prostu całkowicie błędne.
Najlepszym wyborem dla PostgreSQL jest po prostu unikanie projektowania tabel według standardów kodowania.
Podsumowanie
Te techniki słów kluczowych (w porównaniu z operatorami) są również dostępne w Oracle. Są bardziej wieloplatformowe i mniej niejednoznaczne. Już samo to uczyniłoby je najlepszymi praktykami.
Co więcej, przy niewłaściwym użyciu ujawniają błędy logiczne. W przypadku wszelkich prac programistycznych w PostgreSQL jednostronnie zalecamy używanie jawnych słów kluczowych.