Join
데이터베이스 내에서 여러 개의 테이블의 레코드들을 키를 기준으로 조합하여 하나의 열로 나타내는 구문입니다.
A JOIN B ON A.ID = B.ID : 테이블 A, B에서 ID가 같은 레코드끼리 묶어 데이터를 조합합니다.
집합으로 표현할 때 기본 JOIN인 INNER JOIN 경우 A 위치에 해당하는 결과를 냅니다.
Join의 종류
- INNER JOIN : A
- LEFT OUTER JOIN : B + A
- RIGHT OUTER JOIN : A + C
LEFT, RIGHT OUTER JOIN 결과 A에 해당하는 부분은 모든 필드가 채워지지만 B, C에 해당하는 부분은 채워 넣을 데이터가 없으므로 NULL 값으로 채워지게 됩니다.
이외에 두 테이블에서 만들 수 있는 모든 경우의 수, 곱집합을 나타내는 CROSS JOIN, A + B + C 완전 집합을 나타내는 FULL OUTER JOIN 이 있습니다.
MYSQL에서 지원하지 않지만 OUTER JOIN : B + C 범위를 구하고 싶다면 A JOIN B ON A.ID != B.ID를 사용해서 구할 수 있으며 FULL OUTER JOIN 또한 LEFT JOIN, RIGHT JOIN을 UNION 하여 얻을 수 있습니다.
문제
없어진 기록 찾기
차집합을 구하는 문제입니다. LEFT JOIN을 통해 집합을 구하고 WHERE, IS NULL을 통해 교집합을 제거하여 풀 수 있습니다.
SELECT O.ANIMAL_ID, O.NAME
FROM ANIMAL_OUTS AS O
LEFT OUTER JOIN ANIMAL_INS AS I
ON O.ANIMAL_ID = I.ANIMAL_ID
WHERE I.ANIMAL_ID IS NULL
ORDER BY O.ANIMAL_ID;
JOIN을 사용하면 JOIN 자체로 느리기 때문에 차집합을 빠르게 구할 수 있는 상관 서브 쿼리, LIMIT 혹은 TOP을 통해 풀 수 있습니다.
상관 서브쿼리, 서브 쿼리의 결과가 NULL인 경우 교집합이 아니라는 것을 통해 교집합을 빼고 LIMIT, TOP을 이용해 성능을 최적화합니다.
SELECT O.ANIMAL_ID, O.NAME
FROM ANIMAL_OUTS AS O
WHERE (SELECT I.ANIMAL_ID
FROM ANIMAL_INS AS I
WHERE O.ANIMAL_ID = I.ANIMAL_ID
LIMIT 1
)IS NULL
ORDER BY O.ANIMAL_ID;
있었는데요 없었습니다
JOIN을 통해 보호, 입양 모두 된 동물 즉 교집합을 구하고, WHERE 절로 보호 시작일, 입양일 조건을 맞춰줍니다.
SELECT I.ANIMAL_ID, I.NAME
FROM ANIMAL_INS I
JOIN ANIMAL_OUTS O
ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE I.DATETIME > O.DATETIME
ORDER BY I.DATETIME;
오랜 기간 보호한 동물(1)
보호 테이블에는 있으며 입양 테이블에는 없어야 하는 "없어진 기록 찾기 문제"와 같이 차집합을 구하는 문제입니다.
JOIN 사용
SELECT I.NAME, I.DATETIME
FROM ANIMAL_INS I
LEFT OUTER JOIN ANIMAL_OUTS O
ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE O.ANIMAL_ID IS NULL
ORDER BY I.DATETIME
LIMIT 3;
상관 서브 쿼리 사용
SELECT I.NAME, I.DATETIME
FROM ANIMAL_INS I
WHERE (
SELECT ANIMAL_ID FROM ANIMAL_OUTS O
WHERE I.ANIMAL_ID = O.ANIMAL_ID
LIMIT 1
) IS NULL
ORDER BY I.DATETIME
LIMIT 3;
보호소에서 중성화한 동물
JOIN을 통해 교집합을 구하고, WHERE절에서 중성화 조건을 맞추는 문제입니다.
SELECT I.ANIMAL_ID, I.ANIMAL_TYPE, I.NAME
FROM ANIMAL_INS I
JOIN ANIMAL_OUTS O
ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE I.SEX_UPON_INTAKE IN ('Intact Male', 'Intact Female')
AND O.SEX_UPON_OUTCOME NOT IN ('Intact Male', 'Intact Female')
ORDER BY I.ANIMAL_ID;
'스터디 > SQL' 카테고리의 다른 글
[SQL] String, Date 처리 (0) | 2021.03.03 |
---|---|
[SQL] NULL 처리 (0) | 2021.02.28 |
[SQL] GROUP BY (0) | 2021.02.28 |
[SQL] 집계 함수 (0) | 2021.02.26 |
[SQL] SELECT (0) | 2021.02.26 |