Oracle Database
ŁĄCZY
Szukaj…
KRZYŻ DOŁĄCZ
CROSS JOIN
wykonuje połączenie między dwiema tabelami, które nie używa wyraźnej klauzuli łączenia, i powoduje iloczyn kartezjański dwóch tabel. Produkt kartezjański oznacza, że każdy rząd jednego stołu jest łączony z każdym rzędem drugiego stołu w złączeniu. Na przykład, jeśli TABLEA
ma 20 wierszy, a TABLEB
ma 20 wierszy, wynikiem będzie 20*20 = 400
wierszy wyjściowych.
Przykład:
SELECT *
FROM TABLEA CROSS JOIN TABLEB;
Można to również zapisać jako:
SELECT *
FROM TABLEA, TABLEB;
Oto przykład łączenia krzyżowego w SQL między dwiema tabelami:
Przykładowa tabela: TABELA
+-------+---------+
| VALUE | NAME |
+-------+---------+
| 1 | ONE |
| 2 | TWO |
+-------+---------+
Przykładowa tabela: TABELA B
+-------+--------+
| VALUE | NAME |
+-------+--------+
| 3 | THREE |
| 4 | FOUR |
+-------+--------+
Teraz, jeśli wykonasz zapytanie:
SELECT *
FROM TABLEA CROSS JOIN TABLEB;
Wynik:
+-------+--------+-------+--------+
| VALUE | NAME | VALUE | NAME |
+-------+--------+-------+--------+
| 1 | ONE | 3 | THREE |
| 1 | ONE | 4 | FOUR |
| 2 | TWO | 3 | THREE |
| 2 | TWO | 4 | FOUR |
+-------+--------+-------+--------+
Oto jak odbywa się łączenie krzyżowe między dwiema tabelami:
Więcej informacji o Cross Join: dokumentacja Oracle
DOŁĄCZ DO WEWNĘTRZNEGO
WEJŚCIE WEWNĘTRZNE to operacja JOIN, która pozwala określić jawną klauzulę łączenia.
Składnia
TableExpression [INNER] DOŁĄCZ TableExpression {ON booleanExpression | Klauzula USING}
Możesz określić klauzulę łączenia, określając ON za pomocą wyrażenia logicznego.
Zakres wyrażeń w klauzuli ON obejmuje bieżące tabele i wszelkie tabele w zewnętrznych blokach zapytań do bieżącego SELECT. W poniższym przykładzie klauzula ON odnosi się do bieżących tabel:
-- Join the EMP_ACT and EMPLOYEE tables
-- select all the columns from the EMP_ACT table and
-- add the employee's surname (LASTNAME) from the EMPLOYEE table
-- to each row of the result
SELECT SAMP.EMP_ACT.*, LASTNAME
FROM SAMP.EMP_ACT JOIN SAMP.EMPLOYEE
ON EMP_ACT.EMPNO = EMPLOYEE.EMPNO
-- Join the EMPLOYEE and DEPARTMENT tables,
-- select the employee number (EMPNO),
-- employee surname (LASTNAME),
-- department number (WORKDEPT in the EMPLOYEE table and DEPTNO in the
-- DEPARTMENT table)
-- and department name (DEPTNAME)
-- of all employees who were born (BIRTHDATE) earlier than 1930.
SELECT EMPNO, LASTNAME, WORKDEPT, DEPTNAME
FROM SAMP.EMPLOYEE JOIN SAMP.DEPARTMENT
ON WORKDEPT = DEPTNO
AND YEAR(BIRTHDATE) < 1930
-- Another example of "generating" new data values,
-- using a query which selects from a VALUES clause (which is an
-- alternate form of a fullselect).
-- This query shows how a table can be derived called "X"
-- having 2 columns "R1" and "R2" and 1 row of data
SELECT *
FROM (VALUES (3, 4), (1, 5), (2, 6))
AS VALUESTABLE1(C1, C2)
JOIN (VALUES (3, 2), (1, 2),
(0, 3)) AS VALUESTABLE2(c1, c2)
ON VALUESTABLE1.c1 = VALUESTABLE2.c1
-- This results in:
-- C1 |C2 |C1 |2
-- -----------------------------------------------
-- 3 |4 |3 |2
-- 1 |5 |1 |2
-- List every department with the employee number and
-- last name of the manager
SELECT DEPTNO, DEPTNAME, EMPNO, LASTNAME
FROM DEPARTMENT INNER JOIN EMPLOYEE
ON MGRNO = EMPNO
-- List every employee number and last name
-- with the employee number and last name of their manager
SELECT E.EMPNO, E.LASTNAME, M.EMPNO, M.LASTNAME
FROM EMPLOYEE E INNER JOIN
DEPARTMENT INNER JOIN EMPLOYEE M
ON MGRNO = M.EMPNO
ON E.WORKDEPT = DEPTNO
DOŁĄCZ DO LEWEGO ZEWNĘTRZNEGO
LEFT OUTER JOIN
W LEFT OUTER JOIN
wykonuje połączenie między dwiema tabelami, które wymaga wyraźnej klauzuli łączenia, ale nie wyklucza niedopasowanych wierszy z pierwszej tabeli.
Przykład:
SELECT
ENAME,
DNAME,
EMP.DEPTNO,
DEPT.DEPTNO
FROM
SCOTT.EMP LEFT OUTER JOIN SCOTT.DEPT
ON EMP.DEPTNO = DEPT.DEPTNO;
Mimo że składnia ANSI jest zalecanym sposobem, prawdopodobnie bardzo często spotyka się ona ze starszą składnią. Użycie (+)
w ramach warunku określa, którą stronę równania należy uznać za zewnętrzną .
SELECT
ENAME,
DNAME,
EMP.DEPTNO,
DEPT.DEPTNO
FROM
SCOTT.EMP,
SCOTT.DEPT
WHERE
EMP.DEPTNO = DEPT.DEPTNO(+);
Oto przykład lewy zewnętrzny łącznik między dwiema tabelami:
Przykładowa tabela: PRACOWNIK
+-----------+---------+
| NAME | DEPTNO |
+-----------+---------+
| A | 2 |
| B | 1 |
| C | 3 |
| D | 2 |
| E | 1 |
| F | 1 |
| G | 4 |
| H | 4 |
+-----------+---------+
Przykładowa tabela: DEPT
+---------+--------------+
| DEPTNO | DEPTNAME |
+---------+--------------+
| 1 | ACCOUNTING |
| 2 | FINANCE |
| 5 | MARKETING |
| 6 | HR |
+---------+--------------+
Teraz, jeśli wykonasz zapytanie:
SELECT
*
FROM
EMPLOYEE LEFT OUTER JOIN DEPT
ON EMPLOYEE.DEPTNO = DEPT.DEPTNO;
Wynik:
+-----------+---------+---------+--------------+
| NAME | DEPTNO | DEPTNO | DEPTNAME |
+-----------+---------+---------+--------------+
| F | 1 | 1 | ACCOUNTING |
| E | 1 | 1 | ACCOUNTING |
| B | 1 | 1 | ACCOUNTING |
| D | 2 | 2 | FINANCE |
| A | 2 | 2 | FINANCE |
| C | 3 | | |
| H | 4 | | |
| G | 4 | | |
+-----------+---------+---------+--------------+
DOŁĄCZ DO PRAWEJ ZEWNĘTRZNEJ
RIGHT OUTER JOIN
wykonuje połączenie między dwiema tabelami, które wymaga wyraźnej klauzuli łączenia, ale nie wyklucza niedopasowanych wierszy z drugiej tabeli.
Przykład:
SELECT
ENAME,
DNAME,
EMP.DEPTNO,
DEPT.DEPTNO
FROM
SCOTT.EMP RIGHT OUTER JOIN SCOTT.DEPT
ON EMP.DEPTNO = DEPT.DEPTNO;
Ponieważ SCOTT.DEPT
są niedopasowane wiersze SCOTT.DEPT
, ale niedopasowane wiersze SCOTT.EMP
nie, powyższe jest równoważne z następującą instrukcją używającą LEFT OUTER JOIN
.
SELECT
ENAME,
DNAME,
EMP.DEPTNO,
DEPT.DEPTNO
FROM
SCOTT.DEPT RIGHT OUTER JOIN SCOTT.EMP
ON DEPT.DEPTNO = EMP.DEPTNO;
Oto przykład prawidłowego łączenia zewnętrznego między dwiema tabelami:
Przykładowa tabela: PRACOWNIK
+-----------+---------+
| NAME | DEPTNO |
+-----------+---------+
| A | 2 |
| B | 1 |
| C | 3 |
| D | 2 |
| E | 1 |
| F | 1 |
| G | 4 |
| H | 4 |
+-----------+---------+
Przykładowa tabela: DEPT
+---------+--------------+
| DEPTNO | DEPTNAME |
+---------+--------------+
| 1 | ACCOUNTING |
| 2 | FINANCE |
| 5 | MARKETING |
| 6 | HR |
+---------+--------------+
Teraz, jeśli wykonasz zapytanie:
SELECT
*
FROM
EMPLOYEE RIGHT OUTER JOIN DEPT
ON EMPLOYEE.DEPTNO = DEPT.DEPTNO;
Wynik:
+-----------+---------+---------+--------------+
| NAME | DEPTNO | DEPTNO | DEPTNAME |
+-----------+---------+---------+--------------+
| A | 2 | 2 | FINANCE |
| B | 1 | 1 | ACCOUNTING |
| D | 2 | 2 | FINANCE |
| E | 1 | 1 | ACCOUNTING |
| F | 1 | 1 | ACCOUNTING |
| | | 5 | MARKETING |
| | | 6 | HR |
+-----------+---------+---------+--------------+
Odpowiednikiem składni Oracle (+) dla zapytania jest:
SELECT *
FROM EMPLOYEE, DEPT
WHERE EMPLOYEE.DEPTNO(+) = DEPT.DEPTNO;
DOŁĄCZ DO ZEWNĘTRZNEGO
FULL OUTER JOIN
wykonuje połączenie między dwiema tabelami, które wymaga jawnej klauzuli łączenia, ale nie wyklucza niedopasowanych wierszy w żadnej tabeli. Innymi słowy, zwraca wszystkie wiersze w każdej tabeli.
Przykład:
SELECT
*
FROM
EMPLOYEE FULL OUTER JOIN DEPT
ON EMPLOYEE.DEPTNO = DEPT.DEPTNO;
Oto przykład pełnego połączenia zewnętrznego między dwiema tabelami:
Przykładowa tabela: PRACOWNIK
+-----------+---------+
| NAME | DEPTNO |
+-----------+---------+
| A | 2 |
| B | 1 |
| C | 3 |
| D | 2 |
| E | 1 |
| F | 1 |
| G | 4 |
| H | 4 |
+-----------+---------+
Przykładowa tabela: DEPT
+---------+--------------+
| DEPTNO | DEPTNAME |
+---------+--------------+
| 1 | ACCOUNTING |
| 2 | FINANCE |
| 5 | MARKETING |
| 6 | HR |
+---------+--------------+
Teraz, jeśli wykonasz zapytanie:
SELECT
*
FROM
EMPLOYEE FULL OUTER JOIN DEPT
ON EMPLOYEE.DEPTNO = DEPT.DEPTNO;
Wynik
+-----------+---------+---------+--------------+
| NAME | DEPTNO | DEPTNO | DEPTNAME |
+-----------+---------+---------+--------------+
| A | 2 | 2 | FINANCE |
| B | 1 | 1 | ACCOUNTING |
| C | 3 | | |
| D | 2 | 2 | FINANCE |
| E | 1 | 1 | ACCOUNTING |
| F | 1 | 1 | ACCOUNTING |
| G | 4 | | |
| H | 4 | | |
| | | 6 | HR |
| | | 5 | MARKETING |
+-----------+---------+---------+--------------+
Tutaj kolumny, które nie pasują, zostały zachowane na NULL.
PRZECIĄGNIJ
Antijoin zwraca wiersze z lewej strony predykatu, dla których nie ma odpowiednich wierszy z prawej strony predykatu. Zwraca wiersze, które nie pasują (NIE W) do podzapytania po prawej stronie.
SELECT * FROM employees
WHERE department_id NOT IN
(SELECT department_id FROM departments
WHERE location_id = 1700)
ORDER BY last_name;
Oto przykład funkcji Anti Join między dwiema tabelami:
Przykładowa tabela: PRACOWNIK
+-----------+---------+
| NAME | DEPTNO |
+-----------+---------+
| A | 2 |
| B | 1 |
| C | 3 |
| D | 2 |
| E | 1 |
| F | 1 |
| G | 4 |
| H | 4 |
+-----------+---------+
Przykładowa tabela: DEPT
+---------+--------------+
| DEPTNO | DEPTNAME |
+---------+--------------+
| 1 | ACCOUNTING |
| 2 | FINANCE |
| 5 | MARKETING |
| 6 | HR |
+---------+--------------+
Teraz, jeśli wykonasz zapytanie:
SELECT
*
FROM
EMPLOYEE WHERE DEPTNO NOT IN
(SELECT DEPTNO FROM DEPT);
Wynik:
+-----------+---------+
| NAME | DEPTNO |
+-----------+---------+
| C | 3 |
| H | 4 |
| G | 4 |
+-----------+---------+
Dane wyjściowe pokazują, że tylko wiersze tabeli PRACODAWCY, których DEPTNO nie były obecne w tabeli DEPT.
SEMIJOIN
Zapytanie typu semijoin można wykorzystać na przykład do znalezienia wszystkich działów z co najmniej jednym pracownikiem, którego wynagrodzenie przekracza 2500.
SELECT * FROM departments
WHERE EXISTS
(SELECT 1 FROM employees
WHERE departments.department_id = employees.department_id
AND employees.salary > 2500)
ORDER BY department_name;
Jest to bardziej wydajne niż alternatywy pełnego łączenia, ponieważ wewnętrzne połączenie z pracownikami, a następnie podanie klauzuli where, że pensja musi być większa niż 2500, może zwrócić ten sam dział wiele razy. Powiedz, że jeśli Straż Pożarna ma n
wszystkich pracowników z pensją 3000, select * from departments, employees
z niezbędnym łączeniem na identyfikatorach i naszej klauzuli where zwróci Straż Pożarną n
razy.
PRZYSTĄP
Operacja JOIN
wykonuje połączenie między dwiema tabelami, wykluczając niedopasowane wiersze z pierwszej tabeli. Począwszy od Oracle 9i, JOIN
jest równoważny pod względem funkcji INNER JOIN
. Ta operacja wymaga wyraźnej klauzuli łączenia, w przeciwieństwie do operatorów CROSS JOIN
i NATURAL JOIN
.
Przykład:
select t1.*,
t2.DeptId
from table_1 t1
join table_2 t2 on t2.DeptNo = t1.DeptNo
Dokumentacja Oracle:
NATURALNE DOŁĄCZENIE
NATURAL JOIN nie wymaga żadnych jawnych warunków łączenia; buduje jedno na podstawie wszystkich pól o tej samej nazwie w połączonych tabelach.
create table tab1(id number, descr varchar2(100));
create table tab2(id number, descr varchar2(100));
insert into tab1 values(1, 'one');
insert into tab1 values(2, 'two');
insert into tab1 values(3, 'three');
insert into tab2 values(1, 'ONE');
insert into tab2 values(3, 'three');
Łączenie zostanie wykonane na polach ID i DESCR, wspólnych dla obu tabel:
SQL> select *
2 from tab1
3 natural join
4 tab2;
ID DESCR
---------- ----------
3 three
Kolumny o różnych nazwach nie będą używane w stanie JOIN:
SQL> select *
2 from (select id as id, descr as descr1 from tab1)
3 natural join
4 (select id as id, descr as descr2 from tab2);
ID DESCR1 DESCR2
---------- ---------- ----------
1 one ONE
3 three three
Jeśli połączone tabele nie mają wspólnych kolumn, zostanie wykonane JOIN bez żadnych warunków:
SQL> select *
2 from (select id as id1, descr as descr1 from tab1)
3 natural join
4 (select id as id2, descr as descr2 from tab2);
ID1 DESCR1 ID2 DESCR2
---------- ---------- ---------- ----------
1 one 1 ONE
2 two 1 ONE
3 three 1 ONE
1 one 3 three
2 two 3 three
3 three 3 three