SQL JOIN 및 다른 유형의 JOIN


244

SQL이란 무엇이며 JOIN다른 유형은 무엇입니까?

답변:


330

W3schools 의 일러스트 :


INNER JOIN-두 테이블의 조건과 일치하는 레코드 만


LEFT JOIN-표 2의 조건과 일치하는 레코드와 함께 표 1의 모든 레코드


RIGHT JOIN-조건과 일치하는 표 1의 레코드와 함께 표 2의 모든 레코드


FULL OUTER JOIN-왼쪽 및 오른쪽 외부 조인의 조합은 ON 절과 일치하지만 두 테이블을 모두 보존합니다.



27
@KNU w3fools는 사진에 대한 아이디어를 얻은 곳에서 크레딧을 제공해야합니다. 참조 SQL의 시각화 조인 제프 앳 우드에 의해 (예, SO 공동 저술 한)와 Ligaya Turmelle로 연결된 기사 제프 생각이있어 그것을 explanded.
ypercubeᵀᴹ

2
@avi 왼쪽 및 오른쪽 조인은 조인이 기반으로하는 기본 테이블이 무엇인지 신경 쓰지 않으면 비슷합니다.
Anup

2
@ philipxy : 그것은 이상한 정의입니다 (정확한 경우에도). 그러나 오히려 다른 방향으로 가고 크로스 조인으로 시작한 다음 내부 조인을 "빌드"하고 싶습니다. 결국, 단순한 크로스 조인 개념은 이러한 비공식적이고 부정확 한 벤 다이어그램 시각화를 무효화합니다.
Lukas Eder

1
이 그림은 공용체가 완전 외부 조인과 동일하고 교차점이 내가 아는 한 정확하지 않은 내부 조인과 동일하다는 것을 암시하는 것으로 보입니다.
mightyWOZ

1
@DevDave, 대중의 믿음과는 달리-그림은 천 단어의 가치가 없습니다. 다음 답변을 참조하십시오.
hyankov

248

무엇입니까 SQL JOIN?

SQL JOIN 두 개 이상의 데이터베이스 테이블에서 데이터를 검색하는 방법입니다.

다른 무엇입니까 SQL JOIN?

총 5 개가 JOIN있습니다. 그들은 :

  1. JOIN or INNER JOIN
  2. OUTER JOIN

     2.1 LEFT OUTER JOIN or LEFT JOIN
     2.2 RIGHT OUTER JOIN or RIGHT JOIN
     2.3 FULL OUTER JOIN or FULL JOIN

  3. NATURAL JOIN
  4. CROSS JOIN
  5. SELF JOIN

1. 가입 또는 내부 가입 :

이러한 종류의 JOIN에서 두 테이블의 조건과 일치하는 모든 레코드를 가져 오며 일치하지 않는 두 테이블의 레코드는보고되지 않습니다.

다시 말해, 다음 두 가지 INNER JOIN사실에 기초합니다. 두 테이블에서 일치하는 항목 만 나열되어야합니다.

• 그래도 참고 JOIN다른없는 JOIN키워드 (같은 INNER, OUTER, LEFT, 등)가있다 INNER JOIN. 다시 말해, 다음 JOIN에 대한 구문 설탕입니다 INNER JOIN( JOIN과 INNER JOIN의 차이점 참조 ).

2. 외부 가입 :

OUTER JOIN 검색

한 테이블에서 일치하는 행과 다른 테이블의 모든 행 또는 모든 테이블의 모든 행 (일치가 있는지 여부는 중요하지 않음)입니다.

외부 조인에는 세 가지 종류가 있습니다.

2.1 왼쪽 외부 조인 또는 왼쪽 조인

이 조인은 오른쪽 테이블의 일치하는 행과 함께 왼쪽 테이블의 모든 행을 반환합니다. 오른쪽 테이블에 일치하는 열이 없으면 NULL값 을 반환 합니다.

2.2 오른쪽 외부 조인 또는 오른쪽 조인

JOIN모든 반환 왼쪽 테이블에서 일치하는 행과 함께 오른쪽 테이블에서 행. 왼쪽 테이블에 일치하는 열이 없으면 NULL값 을 반환 합니다.

2.3 전체 외부 가입 또는 전체 가입

JOIN콤바인 LEFT OUTER JOINRIGHT OUTER JOIN. 조건이 충족되면 두 테이블에서 행을 반환하고 NULL일치하지 않으면 값을 반환 합니다.

다시 말해, OUTER JOIN다음 중 하나에 해당합니다. 테이블 중 하나 (오른쪽 또는 왼쪽) 또는 테이블 (FULL) 중 일치하는 항목 만 나열해야합니다.

Note that `OUTER JOIN` is a loosened form of `INNER JOIN`.

3. 자연 가입 :

두 가지 조건을 기반으로합니다.

  1. JOIN평등에 대한 동일한 이름을 가진 모든 컬럼에 이루어집니다.
  2. 결과에서 중복 열을 제거합니다.

이것은 본질적으로 더 이론적 인 것으로 보이며 결과적으로 대부분의 DBMS는 이것을 지원하지 않아도됩니다.

4. 크로스 가입 :

관련된 두 테이블의 카티 전 곱입니다. 의 결과는 CROSS JOIN대부분의 상황에서 의미가 없습니다. 또한, 우리는 이것을 전혀 필요로하지 않을 것입니다 (또는 최소한 정확해야합니다).

5. 셀프 가입 :

그것은 다른 양식을하지 않습니다 JOIN오히려 그것이이다, JOIN( INNER, OUTER자체 테이블 등).

연산자 기반 조인

JOIN절에 사용 된 연산자에 따라 두 가지 유형이있을 수 있습니다 JOIN. 그들은

  1. 동등 가입
  2. 세타 가입

1. 동일 가입 :

모든 JOIN유형 ( INNER, OUTER등)에 대해 등호 연산자 (=) 만 사용하는 경우, JOIN는입니다 EQUI JOIN.

2. 세타 가입 :

이것은 동일 EQUI JOIN하지만>, <,> = 등과 같은 다른 모든 연산자를 허용합니다.

많은 사람들이 모두 고려 EQUI JOIN하고 세타가 JOIN유사 INNER, OUTERJOIN의. 그러나 나는 그것이 실수라고 생각하고 아이디어를 모호하게 만듭니다. 때문에 INNER JOIN, OUTER JOIN등 모든 테이블 및 반면 데이터와 연결 EQUI JOIN하고 THETA JOIN단지 우리가 이전에 사용하는 사업자와 연결되어 있습니다.

다시 말하지만, NATURAL JOIN어떤 종류의 "특별한" 것으로 간주하는 사람들이 많이 EQUI JOIN있습니다. 사실, 내가 언급 한 첫 번째 조건 때문에 사실입니다 NATURAL JOIN. 그러나 우리는 이것을 단순히 NATURAL JOIN혼자 로 제한 할 필요는 없습니다 . INNER JOINs OUTER JOIN등도 EQUI JOIN너무 될 수 있습니다 .


2
비교적 새로운 LATERAL JOIN이 있습니다. SELECT * FROM r1, LATERAL fx (r1)
Pavel Stehule

13
이것이 합리적으로 보이지만 유용한 정보를 전달하는 방식으로 "SQL 조인이란 무엇인가"라고 대답하지는 않습니다. 대답은 전체적으로 이미 질문을하는 사람들이 아니라 조인을 이해하는 사람들을위한 참고 문헌입니다. 또한 주장을 뒷받침하고 (정식 답변을하는 경우 적절 함) 외부 자료를 통해 추가 설명을 제공하기위한 참고 자료도 생략합니다. 새로운 SQL 사용자를 연결하기 위해 정식 답변을 작성하려는 경우 공백, 특히 "조인이란 무엇입니까"부분을 채우는 것이 좋습니다.
Craig Ringer

몇 가지 예를 들어 줄 수 있습니까?
avi

67

정의:


JOINS는 여러 테이블에서 동시에 결합 된 데이터를 쿼리하는 방법입니다.

JOINS 유형 :


RDBMS와 관련하여 5 가지 유형의 조인이 있습니다.

  • 동등 조인 : 동일 조건에 따라 두 테이블의 공통 레코드를 결합합니다. 기술적으로, 항등 연산자 (=)를 사용하여 한 테이블의 기본 키 값과 다른 테이블의 외래 키 값을 비교하여 조인하므로 결과 집합에는 두 테이블의 공통 (일치 된) 레코드가 포함됩니다. 구현에 대해서는 INNER-JOIN을 참조하십시오.

  • 자연 결합 : SELECT 조작이 중복 열을 생략하는 Equi-Join의 개선 된 버전입니다. 구현에 대해서는 INNER-JOIN을 참조하십시오.

  • 동일하지 않은 조인 : 조인 조건이 동일한 연산자 (=) 이외의 다른 연산자를 사용하는 경우 동일 조인의 반대입니다 (예 :! =, <=,> =,>, <또는 BETWEEN 등). 구현에 대해서는 INNER-JOIN을 참조하십시오.

  • 자체 결합 : : 테이블이 자체 결합 된 사용자 정의 결합 동작. 이는 일반적으로 자체 참조 테이블 (또는 단항 관계 엔터티)을 쿼리하는 데 필요합니다. 구현에 대해서는 INNER-JOIN을 참조하십시오.

  • 직교 곱 : 조건없이 두 테이블의 모든 레코드를 교차 결합합니다. 기술적으로 WHERE-Clause가없는 쿼리 결과 집합을 반환합니다.

SQL 문제와 발전에 따라 3 가지 유형의 조인이 있으며 이러한 유형의 조인을 사용하여 모든 RDBMS 조인을 수행 할 수 있습니다.

  1. INNER-JOIN : 두 테이블에서 일치하는 행을 병합 (또는 결합)합니다. 일치는 테이블의 공통 열과 비교 작업을 기반으로 수행됩니다. 평등 기반 조건 인 경우 : EQUI-JOIN 수행, 그렇지 않으면 Non-EQUI-Join

  2. OUTER-JOIN : 두 테이블에서 일치하는 행과 일치하지 않는 행을 NULL 값으로 병합 (또는 결합)합니다. 그러나 하위 유형 (LEFT OUTER JOIN 및 RIGHT OUTER JOIN)으로 첫 번째 테이블 또는 두 번째 테이블에서 일치하지 않는 행을 선택하는 것과 같이 일치하지 않는 행의 선택을 사용자 정의 할 수 있습니다.

    2.1. LEFT Outer JOIN (일명 LEFT-JOIN) : 두 테이블에서 일치하는 행을 리턴하고 LEFT 테이블 (즉, 첫 번째 테이블)에서만 일치하지 않는 행을 리턴합니다.

    2.2. RIGHT 외부 조인 (일명 RIGHT-JOIN) : 두 테이블에서 일치하는 행을 반환하고 RIGHT 테이블에서만 일치하지 않는 행을 반환합니다.

    2.3. FULL OUTER JOIN (일명 OUTER JOIN) : 두 테이블에서 일치하고 일치하지 않는 결과를 반환합니다.

  3. CROSS-JOIN : 이 조인은 Cartesian 제품을 수행하는 대신 병합 / 결합하지 않습니다.

여기에 이미지 설명을 입력하십시오 참고 : 자체 JOIN은 요구 사항에 따라 INNER-JOIN, OUTER-JOIN 및 CROSS-JOIN을 통해 달성 할 수 있지만 테이블은 자체적으로 조인해야합니다.

자세한 내용은:

예 :

1.1 : INNER-JOIN : 동일 조인 구현

SELECT  *
FROM Table1 A 
 INNER JOIN Table2 B ON A.<Primary-Key> =B.<Foreign-Key>;

1.2 : INNER-JOIN : Natural-JOIN 구현

Select A.*, B.Col1, B.Col2          --But no B.ForeignKeyColumn in Select
 FROM Table1 A
 INNER JOIN Table2 B On A.Pk = B.Fk;

1.3 : 비 동등 조인 구현의 INNER-JOIN

Select *
 FROM Table1 A INNER JOIN Table2 B On A.Pk <= B.Fk;

1.4 : SELF-JOIN을 사용한 INNER-JOIN

Select *
 FROM Table1 A1 INNER JOIN Table1 A2 On A1.Pk = A2.Fk;

2.1 : OUTER JOIN (전체 외부 조인)

Select *
 FROM Table1 A FULL OUTER JOIN Table2 B On A.Pk = B.Fk;

2.2 : 왼쪽 가입

Select *
 FROM Table1 A LEFT OUTER JOIN Table2 B On A.Pk = B.Fk;

2.3 : 오른쪽 가입

Select *
 FROM Table1 A RIGHT OUTER JOIN Table2 B On A.Pk = B.Fk;

3.1 : 크로스 조인

Select *
 FROM TableA CROSS JOIN TableB;

3.2 : 크로스 조인-셀프 조인

Select *
 FROM Table1 A1 CROSS JOIN Table1 A2;

//또는//

Select *
 FROM Table1 A1,Table1 A2;

레이블 "표 1"& "표 2"및 부적절한 아래의 라벨, 그들은 그림 출신의 intersect/ except/ union; 여기서 원은 번호가 매겨진 레이블과 같이 left& 로 반환되는 행 right join입니다. AXB 사진은 말도 안됩니다. cross join= inner join on 1=1&는 첫 번째 다이어그램의 특별한 경우입니다.
philipxy

SQL-92가을 정의한다고 언급 할 가치가 UNION JOIN있습니다. 이제 SQL : 2003에서 더 이상 사용되지 않습니다.
꿰뚫는

40

흥미롭게도 대부분의 다른 답변에는 다음 두 가지 문제가 있습니다.

나는 최근에 주제에 대한 기사를 작성했습니다 : SQL 에서 테이블에 참여하는 여러 가지 방법에 대한 아마도 불완전하고 포괄적 인 안내서 . 여기에서 요약합니다.

최우선 : JOIN은 데카르트 제품입니다

JOIN 이 두 개의 조인 된 테이블 사이에 데카르트 곱을 작성하기 때문에 벤 다이어그램이이를 부정확하게 설명하는 이유 입니다. Wikipedia는이를 잘 보여줍니다.

여기에 이미지 설명을 입력하십시오

직교 곱의 SQL 구문은 CROSS JOIN입니다. 예를 들면 다음과 같습니다.

SELECT *

-- This just generates all the days in January 2017
FROM generate_series(
  '2017-01-01'::TIMESTAMP,
  '2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
  INTERVAL '1 day'
) AS days(day)

-- Here, we're combining all days with all departments
CROSS JOIN departments

어느 테이블의 모든 행을 다른 테이블의 모든 행과 결합합니다.

출처:

+--------+   +------------+
| day    |   | department |
+--------+   +------------+
| Jan 01 |   | Dept 1     |
| Jan 02 |   | Dept 2     |
| ...    |   | Dept 3     |
| Jan 30 |   +------------+
| Jan 31 |
+--------+

결과:

+--------+------------+
| day    | department |
+--------+------------+
| Jan 01 | Dept 1     |
| Jan 01 | Dept 2     |
| Jan 01 | Dept 3     |
| Jan 02 | Dept 1     |
| Jan 02 | Dept 2     |
| Jan 02 | Dept 3     |
| ...    | ...        |
| Jan 31 | Dept 1     |
| Jan 31 | Dept 2     |
| Jan 31 | Dept 3     |
+--------+------------+

쉼표로 구분 된 테이블 목록을 작성하면 다음과 같이됩니다.

-- CROSS JOINing two tables:
SELECT * FROM table1, table2

내부 가입 (Theta-JOIN)

INNER JOIN단지는 여과 CROSS JOIN필터 선언문이 호출되는 경우 Theta관계 대수에서.

예를 들어 :

SELECT *

-- Same as before
FROM generate_series(
  '2017-01-01'::TIMESTAMP,
  '2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
  INTERVAL '1 day'
) AS days(day)

-- Now, exclude all days/departments combinations for
-- days before the department was created
JOIN departments AS d ON day >= d.created_at

키워드 INNER는 선택 사항입니다 (MS Access 제외).

( 결과 예제는 기사를 참조하십시오 )

동등한 참여

Theta-JOIN의 특별한 종류는 우리가 가장 많이 사용하는 equi JOIN입니다. 술어는 한 테이블의 기본 키를 다른 테이블의 외래 키와 결합합니다. 설명을 위해 Sakila 데이터베이스 를 사용하면 다음 과 같이 쓸 수 있습니다.

SELECT *
FROM actor AS a
JOIN film_actor AS fa ON a.actor_id = fa.actor_id
JOIN film AS f ON f.film_id = fa.film_id

이것은 모든 배우를 영화와 결합합니다.

또는 일부 데이터베이스에서 :

SELECT *
FROM actor
JOIN film_actor USING (actor_id)
JOIN film USING (film_id)

USING()구문은 동작의 테이블을 가입하고 그 두 열에 동등 술어를 작성 양쪽 있어야 열을 지정 가능하다.

자연 가입

다른 답변에서는이 "JOIN 유형"을 별도로 나열했지만 의미가 없습니다. Theta-JOIN 또는 INNER JOIN의 특수한 경우 인 equi JOIN의 구문 설탕 양식 일뿐입니다. NATURAL JOIN은 단순히 결합되는 두 테이블에 공통 인 모든 컬럼을 수집 하고USING() 해당 컬럼을 결합합니다 . 실수로 일치하기 때문에 ( Sakila 데이터베이스의LAST_UPDATE 열과 같은) 거의 유용하지 않습니다 .

구문은 다음과 같습니다.

SELECT *
FROM actor
NATURAL JOIN film_actor
NATURAL JOIN film

외부 가입

이제는 몇 가지 직교 곱을 만드는 OUTER JOIN것과는 조금 다릅니다 . 우리는 쓸 수있다:INNER JOINUNION

-- Convenient syntax:
SELECT *
FROM a LEFT JOIN b ON <predicate>

-- Cumbersome, equivalent syntax:
SELECT a.*, b.*
FROM a JOIN b ON <predicate>
UNION ALL
SELECT a.*, NULL, NULL, ..., NULL
FROM a
WHERE NOT EXISTS (
  SELECT * FROM b WHERE <predicate>
)

아무도 후자를 쓰지 않기를 원하므로 OUTER JOIN데이터베이스에 최적화되어 있습니다.

마찬가지로 INNER키워드 OUTER는 선택 사항입니다.

OUTER JOIN 세 가지 맛이 있습니다.

  • LEFT [ OUTER ] JOIN: JOIN표현식 의 왼쪽 테이블이 위와 같이 공용체에 추가됩니다.
  • RIGHT [ OUTER ] JOIN: JOIN표현식 의 오른쪽 테이블이 위와 같이 공용체에 추가됩니다.
  • FULL [ OUTER ] JOIN: JOIN표현식 의 두 테이블이 위에 표시된대로 공용체에 추가됩니다.

이 모든 키워드 USING()또는 키워드와 결합 할 수 있습니다 NATURAL( 실제로는 NATURAL FULL JOIN최근에 실제 사용 사례를 가졌습니다 )

대체 구문

Oracle과 SQL Server에는 역사적으로 사용되지 않는 몇 가지 OUTER JOIN구문이 있습니다.이 구문은 SQL 표준이 이에 대한 구문을 갖기 전에 이미 지원 되었습니다.

-- Oracle
SELECT *
FROM actor a, film_actor fa, film f
WHERE a.actor_id = fa.actor_id(+)
AND fa.film_id = f.film_id(+)

-- SQL Server
SELECT *
FROM actor a, film_actor fa, film f
WHERE a.actor_id *= fa.actor_id
AND fa.film_id *= f.film_id

그렇게 말했지만이 구문을 사용하지 마십시오. 오래된 블로그 게시물 / 레거시 코드에서 인식 할 수 있도록 여기에 나열하십시오.

분할 OUTER JOIN

이를 아는 사람은 거의 없지만 SQL 표준은 파티션을 지정 OUTER JOIN하고 Oracle 은이를 구현합니다. 다음과 같이 쓸 수 있습니다.

WITH

  -- Using CONNECT BY to generate all dates in January
  days(day) AS (
    SELECT DATE '2017-01-01' + LEVEL - 1
    FROM dual
    CONNECT BY LEVEL <= 31
  ),

  -- Our departments
  departments(department, created_at) AS (
    SELECT 'Dept 1', DATE '2017-01-10' FROM dual UNION ALL
    SELECT 'Dept 2', DATE '2017-01-11' FROM dual UNION ALL
    SELECT 'Dept 3', DATE '2017-01-12' FROM dual UNION ALL
    SELECT 'Dept 4', DATE '2017-04-01' FROM dual UNION ALL
    SELECT 'Dept 5', DATE '2017-04-02' FROM dual
  )
SELECT *
FROM days 
LEFT JOIN departments 
  PARTITION BY (department) -- This is where the magic happens
  ON day >= created_at

결과의 일부 :

+--------+------------+------------+
| day    | department | created_at |
+--------+------------+------------+
| Jan 01 | Dept 1     |            | -- Didn't match, but still get row
| Jan 02 | Dept 1     |            | -- Didn't match, but still get row
| ...    | Dept 1     |            | -- Didn't match, but still get row
| Jan 09 | Dept 1     |            | -- Didn't match, but still get row
| Jan 10 | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 11 | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 12 | Dept 1     | Jan 10     | -- Matches, so get join result
| ...    | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 31 | Dept 1     | Jan 10     | -- Matches, so get join result

여기서 요점은 조인의 분할 된쪽에있는 모든 행 JOIN이 "JoIN의 다른 쪽"에있는 것과 일치 하는지 여부에 관계없이 결과에 적용된다는 것입니다. 간단히 말해 : 보고서에서 희소 데이터를 채우는 것입니다. 굉장히 유용하다!

세미 조인

진심이야? 다른 답변이 없습니까? 물론 , 불행히도 (아래의 ANTI JOIN과 마찬가지로) SQL에는 네이티브 구문이 없기 때문에 아닙니다 . 그러나 우리는 사용할 수 있습니다 IN()EXISTS()영화에서 연주 한 모든 배우를 찾기 위해, 예를 :

SELECT *
FROM actor a
WHERE EXISTS (
  SELECT * FROM film_actor fa
  WHERE a.actor_id = fa.actor_id
)

WHERE a.actor_id = fa.actor_id반이 술어 가입으로 술어는 역할을합니다. 믿지 않으면 Oracle과 같은 실행 계획을 확인하십시오. 데이터베이스가 EXISTS()술어가 아닌 SEMI JOIN 조작을 실행 함을 알 수 있습니다.

여기에 이미지 설명을 입력하십시오

안티 가입

이 SEMI의 정반대입니다 가입 ( 사용하지 않도록주의해야 NOT IN하지만 , 그것은 중요한주의를 가지고로)

영화가없는 배우는 다음과 같습니다.

SELECT *
FROM actor a
WHERE NOT EXISTS (
  SELECT * FROM film_actor fa
  WHERE a.actor_id = fa.actor_id
)

일부 사람들 (특히 MySQL 사용자)도 다음과 같이 ANTI JOIN을 작성합니다.

SELECT *
FROM actor a
LEFT JOIN film_actor fa
USING (actor_id)
WHERE film_id IS NULL

역사적인 이유는 성능이라고 생각합니다.

측면 가입

세상에, 이건 너무 멋지다. 나는 그것을 언급하는 유일한 사람입니까? 다음은 멋진 검색어입니다.

SELECT a.first_name, a.last_name, f.*
FROM actor AS a
LEFT OUTER JOIN LATERAL (
  SELECT f.title, SUM(amount) AS revenue
  FROM film AS f
  JOIN film_actor AS fa USING (film_id)
  JOIN inventory AS i USING (film_id)
  JOIN rental AS r USING (inventory_id)
  JOIN payment AS p USING (rental_id)
  WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!
  GROUP BY f.film_id
  ORDER BY revenue DESC
  LIMIT 5
) AS f
ON true

배우 당 최고 5 개의 수입 영화를 찾을 수 있습니다. TOP-N-perthing 쿼리가 필요할 때마다 LATERAL JOIN친구가됩니다. SQL Server 사용자 인 JOIN경우 이름 아래 에서이 유형 을 알고 있습니다APPLY

SELECT a.first_name, a.last_name, f.*
FROM actor AS a
OUTER APPLY (
  SELECT f.title, SUM(amount) AS revenue
  FROM film AS f
  JOIN film_actor AS fa ON f.film_id = fa.film_id
  JOIN inventory AS i ON f.film_id = i.film_id
  JOIN rental AS r ON i.inventory_id = r.inventory_id
  JOIN payment AS p ON r.rental_id = p.rental_id
  WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!
  GROUP BY f.film_id
  ORDER BY revenue DESC
  LIMIT 5
) AS f

LATERAL JOIN또는 APPLY표현식이 실제로 여러 행을 생성하는 "상관 된 하위 쿼리" 이므로 부정 행위 일 수 있습니다. 그러나 "상관 된 하위 쿼리"를 허용하면 다음에 대해서도 이야기 할 수 있습니다.

멀티 셋

이것은 실제로 Oracle과 Informix에 의해서만 구현되지만 배열 및 / 또는 XML을 사용하는 PostgreSQL 및 XML을 사용하는 SQL Server에서 에뮬레이션 할 수 있습니다.

MULTISET상관 된 하위 쿼리를 생성하고 결과 행 집합을 외부 쿼리에 중첩시킵니다. 아래 쿼리는 모든 액터를 선택하고 각 액터마다 중첩 된 컬렉션으로 영화를 수집합니다.

SELECT a.*, MULTISET (
  SELECT f.*
  FROM film AS f
  JOIN film_actor AS fa USING (film_id)
  WHERE a.actor_id = fa.actor_id
) AS films
FROM actor

당신이 보았 듯이,이 단지 "지루한"보다 가입의 많은 종류가 있습니다 INNER, OUTER그리고 CROSS JOIN그 일반적으로 언급된다. 내 기사에 자세한 내용이 있습니다. 그리고 Venn 다이어그램 사용을 그만 설명하십시오.


Equijoin은 세타가 평등 한 세타 조인의 특별한 경우입니다. 세타 조인은 내부 조인의 특수한 경우와 유사합니다. Codd가 그들에게 몇 십년을 정의한 후 몇몇 교과서 (들)가 세타 조인을 내부 조인의 유사 인 일반화로 잘못 정의했습니다.
philipxy

@ philipxy : 대답에서 변경해야 할 것이 있습니까? 당신은 편집을 제안 할 수 있습니다 ...
Lukas Eder

10

내 의견으로는 단어보다 더 잘 설명하는 일러스트레이션을 만들었습니다. SQL 조인 설명 테이블


@Niraj 원 A와 B는 A와 B의 행을 포함하지 않습니다. 이들은 크레딧없이 다른 곳에서 맹목적으로 복사됩니다. 내부 조인 케이스에 크로스 조인이 포함되며 1 = 1의 내부 조인입니다. 그림의이 부분들은 어떤 방식으로 "완벽"합니까?
philipxy

@philipxy 죄송하지만 다른 곳에서 복사 한 경우에는 신경 쓰지 않습니다. 위의 그림에서 어느 것이 올바르지 않은지 잘 모르겠습니다. 나를 위해 이것은 괜찮습니다. 교차 결합은 여기에 설명되어 있지 않습니다. 내부 조인에는 포함되어 있지 않습니다.
Niraj

-3

내 애완 동물을 밀어 붙일 것입니다 : USING 키워드.

JOIN의 양쪽에있는 두 테이블의 외래 키 이름이 "id가 ​​아닌 동일한 이름"인 경우 다음을 사용할 수 있습니다.

SELECT ...
FROM customers JOIN orders USING (customer_id)

나는 이것이 매우 실용적이고 읽기 쉽고 자주 사용되지 않는다는 것을 알았습니다.


2
이것은 질문에 대답하지 않습니다. 그것은 질문이나 답변 중 하나의 주석으로 속합니다.
TylerH
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.