Wpis z mikrobloga

Jest tu jakiś specjalista od Oracle SQL?

Mamy zapytanie w ANSI łączące trzy tabele. Daje ono 106 wierszy:

select first_name, last_name, department_name, job_title
from employees e
right join departments d on e.department_id = d.department_id
right join jobs j on e.job_id = j.job_id;

Ale jeżeli przekształcimy je na non-ANSI syntax, to robi się cross join tabeli departments z tabelą jobs, i wychodzi już 600 wierszy:

select first_name, last_name, department_name, e.department_id, d.department_id, j.job_title, e.job_id, j.job_id
from employees e, departments d, jobs j
where e.department_id(+) = d.department_id
and e.job_id(+) = j.job_id;

Dlaczego tak się dzieje? Wiem jak to naprawić, ale może mi ktoś powiedzieć jaka logika za tym stoi? Bo normalnie najpierw łączą się tabele employees z departments, a dopiero później rezultat tego połączenia łączy się z jobs. Ale przy non-ANSI to nie działa.

Jest to domyślna HR schema od Oracle:

--------------- -------- ------------
Employees (107 rows):

EMPLOYEE_ID
FIRST_NAME
LAST_NAME
EMAIL
PHONE_NUMBER
HIRE_DATE
JOB_ID
SALARY
COMMISSION_PCT
MANAGER_ID
DEPARTMENT_ID
-------------- -------- ------------
Departments (27 rows):

DEPARTMENT_ID
DEPARTMENT_NAME
MANAGER_ID
LOCATION_ID
-------------- -------- ------------
Jobs (19 rows):

JOB_ID
JOB_TITLE
MIN_SALARY
MAX_SALARY
--------------- -------- ------------

#sql #oracle #programowanie
  • 3
@Rajtuz czy to cos pomoglo? (gpt4)

Rozumiem problem, z którym się borykasz. Wygląda na to, że doświadczasz problemu wynikającego z różnic w zachowaniu składni ANSI i non-ANSI podczas wykonywania wielokrotnych zewnętrznych łączeń (RIGHT JOINs).

Oto, co się dzieje w obu przypadkach:

1. ANSI Syntax:
- Najpierw wykonuje się prawe łączenie między employees i departments na podstawie department_id.
- Następnie, wynik tego łączenia jest prawie łączony z jobs na podstawie job_id
  • 0
@Volantie: To crossowanie wszystkiego przy non-ANSI i późniejsze filtrowanie ma jakiś sens. Muszę to jeszcze sprawdzić na innych przykładach. Dzięki za pomoc.
logika za tym stoi taka:
łącząc przez joina a=b już robisz filtrację wyniku bo tylko pokaże Ci dane gdzie a=b

no ansi nie na logiki(tu przykład tej "logiki") wychodzi Ci za dużo pewnie niepotrzebnych danych które później w where musisz umiejętnie przefiltrować

są przypadki gdzie powinniśmy użyć cross joina, ale to nie jest ten przypadek

dobre zadanie dla Ciebie - zastanów się w jakim przypadku dobrze tego użyć :)