diff --git a/back/database/img/sql-first-step-33.png b/back/database/img/sql-first-step-33.png new file mode 100644 index 0000000..f7a905b Binary files /dev/null and b/back/database/img/sql-first-step-33.png differ diff --git a/back/database/sql-first-step/sql-first-step-09.md b/back/database/sql-first-step/sql-first-step-09.md new file mode 100644 index 0000000..2378110 --- /dev/null +++ b/back/database/sql-first-step/sql-first-step-09.md @@ -0,0 +1,176 @@ +--- +id: sql-first-step-09 +title: 7장 복수의 테이블 다루기 +authors: hank +tags: [hank, SQL 첫걸음, mysql, JOIN] +keywords: [SQL 첫걸음, mysql, JOIN, LEFT JOIN, OUTER JOIN, FULL JOIN, RIGHT JOIN, UNION] +last_update: + date: 12/22/2023 + author: hank +--- + +## 집합 연산 + +관계형 데이터베이스의 관계형은 수학 집합론의 관계형 이론에서 유래했습니다. 데이터베이스에서 SELECT해서 조회하는 행들은 하나의 집합으로 간주되곤 하며 키워드들도 집합에 비롯된 것이 많습니다. + +```sql +SELECT * FROM A +UNION (ALL) +SELECT * FROM B; +``` + +수학에서 합집합 기호는 U는 `UNION` 이라는 키워드로 RDBMS에서 사용됩니다. `UNION` 을 이용하면 여러 개의 SELECT 명령을 하나로 묶을 수 있습니다. + +- 열의 개수와 자료형이 같아야만 사용할 수 있습니다. +- ALL 키워드를 붙이면 중복까지 모두 합치고 붙이지 않으면 DISTINCT와 같이 1개만 남깁니다. + +```sql +SELECT a FROM A +UNION +SELECT b FROM B ORDER BY b; +``` + +UNION에서 정렬을 사용하고 싶을 경우 마지막 SELECT 명령 뒤에 ORDER BY를 지정해줍니다. + +```sql +SELECT a FROM A +INTERSECT +SELECT b FROM B; + +SELECT a FROM A +EXCEPT +SELECT b FROM B; +``` + +교집합은 INTERSECT, 차집합은 EXCEPT를 사용합니다. + +
+ +## JOIN (테이블 결합) + +테이블과 테이블을 한번에 조회하는 것을 JOIN(테이블 결합)이라고 부릅니다. + +### implicit join + +```sql +SELECT D.name +FROM employee AS E, department AS D +WHERE E.id = 1 and E.dept_id = D.id; +``` + +FROM 절에는 테이블들만 나열하고 WHERE 절에서 join condition을 명시하는 방식입니다. 오래된 스타일이고 WHERE 절에 selection 조건과 join 조건이 같이 있기 때문에 가독성이 떨어집니다. + + +
+ +### explicit join + +```sql +SELECT D.name +FROM employee AS E +JOIN department AS D ON E.dept_id = D.id +WHERE E.id = 1; +``` + +FROM 절에 JOIN 키워드와 함께 joined table들을 명시하는 방식입니다. 요즘에는 JOIN ON 키워드를 활용하여 테이블을 JOIN합니다. + +
+ +### INNER JOIN + +```sql +SELECT D.name +FROM employee AS E +(INNER) JOIN department AS D ON E.dept_id = D.id; +``` + +교차결합으로 계산된 곱집합에서 원하는 조합을 검색하는 것을 INNER JOIN(내부결합)이라고 부릅니다. INNER JOIN은 두 테이블에서 join condition을 만족하는 레코드들로 결과를 만듭니다. JOIN하려는 컬럼의 값이 NULL인 경우 테이블의 레코드가 무시되는 결과가 나옵니다. + +- JOIN 키워드에는 INNER 키워드가 생략되어있음 + +
+ +### OUTER JOIN + +```sql +SELECT * FROM X LEFT (OUTER) JOIN Y ON 조건문; +SELECT * FROM X RIGHT (OUTER) JOIN Y ON 조건문; +SELECT * FROM X FULL (OUTER) JOIN Y ON 조건문; // postgres만 지원 +``` + +OUTER JOIN은 job condition을 만족하지 않는 레코드들도 결과에 포함하는 JOIN입니다. + +- `LEFT` : X의 조건문을 만족하지 않는 레코드를 포함되지만 Y 테이블의 레코드는 제외됩니다. +- `RIGHT` : Y의 조건문을 만족하지 않는 레코드가 포함되지만 X 테이블의 레코드는 제외됩니다. +- `FULL` : X,Y 테이블 모두 제외되지 않고 포함됩니다. + +
+ +### equi join + +```sql +SELECT * FROM X JOIN Y ON X.id = Y.id; +``` + +INNER, OUTER 구분없이 join condition에서 =(equality comparator)를 사용하는 JOIN을 의미합니다. + +- INNER JOIN으로만 한정해서 부르는 경우도 있습니다. + +
+ +### `USING` + +```sql +SELECT * FROM X INNER JOIN Y ON X.id = Y.id; + +SELECT * FROM X INNER JOIN Y USING (id); +``` + +두 테이블을 equi JOIN할 때 attribute의 이름이 같다면 `USING`이라는 키워드를 사용할 수 있습니다. + +- attribute의 개수 제한은 없습니다. +- result에서 두 attribute가 한개로 합쳐집니다. +- INNER, OUTER 상관없이 사용가능합니다. + +
+ +### NATURAL JOIN + +```sql +SELECT * FROM X NATURAL JOIN Y; + +// 같은 의미의 쿼리 +SELECT * FROM X JOIN Y USING(열명1, 열명2...); +``` + +두 테이블에서 같은 이름을 가지는 모든 attribute pair에 대해서 암묵적으로 equi join을 수행해줍니다. + +- 조건문을 따로 작성하지 않습니다. +- attribute들은 모두 AND 조건으로 연속됩니다. + - 이러한 이유때문에 모든 attribute들이 다 같은지 확인하기 때문에 empty set을 받을 확률이 높습니다. + +
+ +### CROSS JOIN (교차결합) + +![img](../img/sql-first-step-33.png) + +```sql +// implicit +SELECT * FROM X, Y; + +// explicit +SELECT * FROM X CROSS JOIN Y; +``` + +FROM 구에 복수의 테이블을 지정하면 교차결합을 합니다. 교차결합은 두 개의 테이블을 곱집합으로 계산합니다. 테이블의 컬럼들이 모두 합쳐지고 왼쪽 테이블의 행 개수 곱하기 오른쪽 테이블의 행만큼 더해진 것을 확인할 수 있습니다. X, Y 테이블에서 X에 Y 개수만큼 곱해져 계산된 것입니다. + +- UNION은 세로로 CROSS JOIN은 가로로 더해지게 됩니다. +- MySQL에서는 cross join = inner join = join입니다. + - INNER JOIN이 ON / USING 키워드없이 사용하면 CROSS JOIN으로 동작합니다. + +
+ +### self join + +테이블이 자기 자신에게 JOIN하는 경우를 의미합니다. \ No newline at end of file