SQL JOIN 및 다양한 유형의 JOIN
SQL이란 입니까?JOIN그리고 다른 종류들은 무엇입니까?
W3 학교의 삽화:




란?SQL JOIN?
SQL JOIN둘 이상의 데이터베이스 테이블에서 데이터를 검색하는 방법입니다.
이 다른가요?SQL JOINs?
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
조인 또는 내부 조인:
이런 식으로JOIN두 테이블의 조건과 일치하는 모든 레코드를 가져오며, 일치하지 않는 두 테이블의 레코드는 보고되지 않습니다.
다른말하면로,하면,INNER JOIN두 테이블 모두에서 일치하는 항목만 나열해야 한다는 단일 사실을 기반으로 합니다.
로 참은 다음과 같습니다.JOIN 어떤 것도JOIN: 키드예워):INNER,OUTER,LEFTetc는 "(으)"입니다.INNER JOIN 다른말하면로,하면,JOIN에 대한 통사적 설탕입니다.INNER JOIN(JOIN과 INER JOIN의 차이 참조).
외부 결합:
OUTER JOIN검색
한 테이블의 일치된 행과 다른 테이블의 모든 행 또는 모든 테이블의 모든 행(일치 여부는 중요하지 않음).
외부 조인에는 세 가지 유형이 있습니다.
2.1 좌측 외측 조인트 또는 좌측 조인트
이 조인은 오른쪽 테이블의 일치하는 행과 함께 왼쪽 테이블의 모든 행을 반환합니다. 오쪽테에일는열이없반으환다니됩면치하이블른을 반환합니다.NULL가치.
2.2 우측 외측 조인트 또는 우측 조인트
것이.JOIN왼쪽 테이블의 일치하는 행과 함께 오른쪽 테이블의 모든 행을 반환합니다.표에 에는 " 왼쪽테에일치열는이없반으환다니됩면하이"를 반환합니다."를 반환합니다.NULL가치.
2.3 완전 외측 결합 또는 완전 결합
것이.JOINLEFT OUTER JOIN그리고.RIGHT OUTER JOIN조건이 충족되면 두 테이블 중 하나에서 행을 반환하고 반환합니다.NULL일치하는 항목이 없을 때 값을 지정합니다.
다른말하면로,하면,OUTER JOIN테이블 중 하나(오른쪽 또는 왼쪽) 또는 두 테이블 모두(전체)에 일치하는 항목만 나열해야 한다는 사실에 기초합니다.
Note that `OUTER JOIN` is a loosened form of `INNER JOIN`.
자연 접합:
두 가지 조건을 기반으로 합니다.
- 그자리의
JOIN동일한 이름을 가진 모든 열에 동일한 이름으로 생성됩니다. - 결과에서 중복 열을 제거합니다.
이것은 본질적으로 더 이론적인 것으로 보이며, 결과적으로 대부분의 DBMS는 이를 지원하지 않습니다.
교차 결합:
관련된 두 표의 데카르트 곱입니다.의 CROSS JOIN대부분의 상황에서 말이 되지 않습니다.게다가, 우리는 이것이 전혀 필요하지 않을 것입니다(정확히 말하자면, 최소한 필요합니다).
자체 결합:
의 다른 형태가 아닙니다.JOIN 그것은 그것려은히오입니다.JOIN(INNER,OUTER등) 테이블 자체에 대한 설명입니다.
연산자 기반 JOIN
용된연에따라에 에 따라 .JOIN절, 두 가지 유형이 있을 수 있습니다.JOIN.
- 에퀴 조인
- 세타 조인
Equi JOIN:
을 위해서라도.JOINtype)INNER,OUTER 연산자(=)만하면 등), 등연산자호사(=)라고 합니다.JOIN입니다.EQUI JOIN.
세타 조인:
이는 다음과 같습니다.EQUI JOIN그러나 >, <, >= 등과 같은 다른 모든 연산자를 허용합니다.
많은 사람들이 둘 다 고려합니다.
EQUI JOIN세타 리고세타그.JOIN와비한과 한.INNER,OUTER타기JOIN하지만 저는 그것이 실수이고 그 생각들을 모호하게 만든다고 강하게 믿습니다. ㅠㅠINNER JOIN,OUTER JOIN등은 모두 표와 그들의 데이터와 연결되어 있는 반면,EQUI JOIN그리고.THETA JOIN전자에서 사용하는 연산자와만 연결됩니다.다시 말하지만, 많은 사람들이 생각합니다.
NATURAL JOIN일종사 "기꾼으 "로서 "사으 "▁some" ""꾼 "EQUI JOIN사실, 사실입니다, 왜냐하면 제가 언급한 첫 번째 조건 때문입니다.NATURAL JOIN하지만, 우리는 단순히 그것을 제한할 필요는 없습니다.NATURAL JOIN고독한INNER JOINs,OUTER JOIN은 등이될수있니다습▁be▁an다니▁could▁s가 될 수 있습니다.EQUI JOIN도 마찬가지야
정의:
JOIN은 여러 테이블에서 함께 결합된 데이터를 동시에 쿼리하는 방법입니다.
조인 유형:
RDBMS와 관련하여 다음과 같은 5가지 유형의 조인이 있습니다.
Equi-Join:동일 조건을 기준으로 두 테이블의 공통 레코드를 결합합니다.기술적으로, 한 테이블의 기본 키 값과 다른 테이블의 외부 키 값을 비교하기 위해 equality-codice_1(=)을 사용하여 조인합니다. 따라서 결과 세트에는 두 테이블의 공통(접두사) 레코드가 포함됩니다.구현에 대한 자세한 내용은 INER-JOIN을 참조하십시오.
자연 결합:SELECT 작업에서 중복 열을 생략하는 Equi-Join의 향상된 버전입니다.구현은 INER-JOIN을 참조하십시오.
비Equi-Join:결합 조건이 등호 연산자(=)가 아닌 다른 용도(예: !=, <=, >=, >, < 또는 BETWEEN 등)인 Equi-join의 역입니다.구현에 대한 자세한 내용은 INER-JOIN을 참조하십시오.
자가 조인:: 테이블이 자신과 결합하는 맞춤형 조인 동작;이는 일반적으로 자체 참조 테이블(또는 단항 관계 엔티티)을 쿼리하는 데 필요합니다.구현에 대한 자세한 내용은 INER-JOINES를 참조하십시오.
데카르트 제품:두 테이블의 모든 레코드를 아무런 조건 없이 교차 결합합니다.기술적으로 WHERE-Clause 없이 쿼리의 결과 집합을 반환합니다.
SQL 문제 및 고급사항에 따라 3가지 유형의 조인이 있으며 이러한 유형의 조인을 사용하여 모든 RDBMS 조인을 수행할 수 있습니다.
INNER-JOIN: 두 테이블에서 일치하는 행을 병합(또는 결합)합니다.일치는 테이블의 공통 열과 테이블의 비교 작업을 기준으로 수행됩니다.동일 기준 조건인 경우: EQUI-JOIN이 수행되고, 그렇지 않은 경우에는 Non-EQ가 수행됩니다.UI 가입.
OUTER-JOIN: 두 테이블에서 일치하는 행과 NULL 값이 일치하지 않는 행을 병합(또는 결합)합니다.그러나 일치하지 않는 행을 사용자 지정할 수 있습니다. 예를 들어 첫 번째 테이블에서 일치하지 않는 행을 선택하거나 하위 유형(LEFT OUTER JOIN 및 RIGHT OUTER JOIN)으로 두 번째 테이블에서 일치하지 않는 행을 선택합니다.
2.1. LEFT Outer JOIN(일명 LEFT-JOIN): 두 테이블에서 일치하는 행과 LEFT 테이블(즉, 첫 번째 테이블)에서만 일치하는 행을 반환합니다.
2.2. RIGHT Outer JOIN(일명 RIGHT-JOIN): 두 테이블에서 일치하는 행과 RIGHT 테이블에서만 일치하지 않는 행을 반환합니다.
2.3. FULL OUTER JOIN(일명 OUTER JOIN): 두 테이블에서 일치하는 것과 일치하지 않는 것을 반환합니다.
CROSS-JOIN: 이 조인은 병합/결합하지 않고 데카르트 제품을 수행합니다.
참고: 필요에 따라 INER-JOIN, OUTER-JOIN 및 CROSS-JOIN을 사용하여 자체 조인을 수행할 수 있지만 테이블을 자체 조인해야 합니다.
예:
1.1: INER-JOIN: Equi-Join 구현
SELECT *
FROM Table1 A
INNER JOIN Table2 B ON A.<Primary-Key> =B.<Foreign-Key>;
1.2: 이너-조인: 자연스러운-조인 구현
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: NON-Equi-Join 구현을 통한 이너-조인
Select *
FROM Table1 A INNER JOIN Table2 B On A.Pk <= B.Fk;
1.4: 내부 결합(Self-
Select *
FROM Table1 A1 INNER JOIN Table1 A2 On A1.Pk = A2.Fk;
2.1: 외측 조인(전체 외측 조인)
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;
//OR//
Select *
FROM Table1 A1,Table1 A2;
흥미롭게도 대부분의 다른 답변은 다음 두 가지 문제로 인해 어려움을 겪고 있습니다.
- 기본적인 결합 형태에만 초점을 맞춥니다.
- 그들은 결합을 시각화하기 위한 부정확한 도구인 벤 다이어그램을 사용합니다(조합에 훨씬 좋습니다).
저는 최근에 "SQL에서 테이블을 조인하는 다양한 방법에 대한 불완전하고 포괄적인 가이드"라는 주제로 기사를 썼습니다. 이 내용은 여기서 요약하겠습니다.
무엇보다도: JOIN은 데카르트 제품입니다.
이것이 벤 다이어그램이 결합된 두 테이블 사이에 데카르트 곱을 만들기 때문에 부정확하게 설명하는 이유입니다.위키피디아는 그것을 잘 보여줍니다.
은 데르트제품의같다다습니음구 입니다.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는 여서필터술호출다니합어를기다▁where호▁called니라고 합니다.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 제외).
(결과 예는 기사를 참조하십시오.
EQUI 조인
특별한 종류의 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 작업 테이블의 양쪽에 있어야 하는 열을 지정할 수 있으며 두 열에 동일한 술어를 만들 수 있습니다.
자연 결합
다른 답변에서는 이 "JOIN 유형"을 별도로 나열했지만, 이는 말이 되지 않습니다.그것은 단지 세타-J의 특별한 경우인 equi JOIN의 구문 설탕 형태입니다.OIN 또는 INER JOIN. 자연스러운 JOIN은 조인 및 조인 중인 두 테이블에 공통적인 모든 열을 수집합니다.USING()(예를 ) 우연한일치 하지 않은 것입니다.LAST_UPDATE열(Sakila 데이터베이스의 열).
구문은 다음과 같습니다.
SELECT *
FROM actor
NATURAL JOIN film_actor
NATURAL JOIN film
외부 결합
지금이다,OUTER JOIN는 와는조 다다니릅과 조금 .INNER JOIN이로 인해UNION여러 데카르트 제품의.작성할 수 있는 내용:
-- 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맛이 : 지 가 맛 이 있 습 니 다 세 니 다 습 있 ▁comes 가 ours지
LEFT [ OUTER ] JOIN의 표JOIN식이 위와 같이 유니언에 추가됩니다.RIGHT [ OUTER ] JOIN의 표JOIN식이 위와 같이 유니언에 추가됩니다.FULL [ OUTER ] JOIN의 두 표JOIN식이 위와 같이 유니언에 추가됩니다.
이 모든 것을 키워드와 결합할 수 있습니다.USING()또는 와 함께NATURAL(최근에 실제 사용 사례가 있었습니다.)
대체 구문
Oracle 및 SQL Server에는 사용되지 않는 몇 가지 과거 구문이 있으며, 이 구문은 다음을 지원합니다.OUTER JOINSQL 표준에 이미 구문이 있습니다.
-- 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의 반대편'에 있는 모든 것과 일치합니다. 긴 이야기는:보고서의 희소 데이터를 채우기 위한 것입니다.매우 유용합니다!
세미 조인트
진짜로?다른 답은 없었나요?물론 그렇지 않습니다. SQL에 네이티브 구문이 없기 때문입니다(아래 ANTI JOIN과 마찬가지로).하지만 우리는 사용할 수 있습니다.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과 같은 실행 계획을 확인하십시오.가 SEMI JOIN이 볼 수 .EXISTS()술어
안티 조인
SEMI JOIN과는 정반대입니다(단, 중요한 주의사항이 있으므로 사용하지 않도록 주의하십시오).
영화에 출연하지 않은 배우들은 다음과 같습니다.
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
배우 1인당 수익률 상위 5개 영화를 발굴할 예정입니다.할 때마다 TOP-N-per-thomething ▁every,때쿼다마-▁top리▁a할요-▁you▁top필▁need▁query▁time-n가---.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에서만 실제로 구현되지만 Postgre에서 에뮬레이트할 수 있는 것으로 알고 있습니다.어레이 및/또는 XML을 사용하는 SQL 및 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
보신 것처럼, "지루한" 것 이상으로 더 많은 유형의 JOIN이 있습니다.INNER,OUTER,그리고.CROSS JOIN일반적으로 언급되는.자세한 내용은 제 기사를 참조하십시오.그리고 제발, 벤 다이어그램을 사용해서 그것들을 설명하는 것을 멈추세요.
제 생각에 저는 말보다 더 잘 설명할 수 있는 그림을 만들었습니다.
저는 저의 불만인 USING 키워드를 밀고 나갈 것입니다.
JOIN의 양쪽 테이블에 올바른 이름("id"가 아닌 동일한 이름)이 있는 경우 다음을 사용할 수 있습니다.
SELECT ...
FROM customers JOIN orders USING (customer_id)
저는 이것이 매우 실용적이고, 읽기 쉽고, 자주 사용되지 않는다는 것을 알게 되었습니다.
언급URL : https://stackoverflow.com/questions/17946221/sql-join-and-different-types-of-joins
'programing' 카테고리의 다른 글
| IBOutlet은 0이지만 스토리보드에 연결되어 있습니다. Swift (0) | 2023.05.13 |
|---|---|
| node.js에서 기본 표준 시간대를 설정하려면 어떻게 해야 합니까? (0) | 2023.05.13 |
| 에서 컴퓨터 이름을 가져오려면 어떻게 해야 합니까?그물 (0) | 2023.05.08 |
| Python에서 임의 문자 생성 (0) | 2023.05.08 |
| OWIN / Katana를 사용하여 Azure에서 데이터 보호 작업에 실패했습니다. (0) | 2023.05.08 |

