SQL JOIN 정리
실제 업무 환경에서는 데이터의 중복 저장을 방지하기 위해 DB를 분리해서 사용하고, JOIN을 사용할 일이 매우 많다.
그래서 관계형 데이터베이스를 관리하기위해 RDBMS (Relation Database management system) 사용하는 것이다.
DB간의 관계를 ERD(Entity-Relation Diagram)으로 표현하는데, 알고 있으면 SQL을 작성하기 훨씬 용이해진다.
(문헌정보학 전공에서 수도 없이 배웠던 ERD… 다시보니 반갑다. 이번 기회에 복습해서 정리해야겠다)
INNER JOIN
/* 지금은 잘 안쓰는 방식
SELECT * FROM users, orders
where users.Id = orders.userId
*/
SELECT *
FROM users
INNER JOIN orders on users.Id = orders.userId
-- 아래 INNER JOIN 명령어를 반복하면 많은 테이블을 계속 연결할 수 있다.
OUTER JOIN (left join, right join)
-- Left JOIN, right JOIN 모두 쓸 수 있지만
-- 보통 LEFT JOIN이 직관적이어서 주로 사용한다
SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name = table2.column_name
SELF JOIN (테이블 1개 안에서 다시 조인)
Rising Temperature (Leet code) https://leetcode.com/problems/rising-temperature/submissions/
-- 리트코드 문제
SELECT today.id
FROM Weather as today
INNER JOIN Weather as yesterday
ON DATE_ADD(yesterday.recordDate, INTERVAL 1 DAY) = today.recorddate
WHERE today.temperature > yesterday.temperature
-- on 다음에 연산도 가능
ON yesterday.recordDate + INTERVAL 1 DAY = today.recordDate
- DATE_ADD(기준날짜, INTERVAL 1 DAY) 단위만큼 더하기 (근데 음수도 가능)
- DATE_SUB(NOW(), INTERVAL 1 DAY) 단위만큼 뺴기
- 단위: YEAR, MONTH, DAY, HOUR, MINUTE, SECOND
UNION
데이터를 위 아래로 합친다고 생각하면 쉽다. UNION을 사용하면 중복은 제거한다.
(ex. 기존 데이터와 최신데이터를 합칠때 자주 사용)
SELECT City FROM Customers
UNION
SELECT City FROM Suppliers
ORDER BY City;
UNION 참고자료: https://www.w3schools.com/sql/sql_union.asp
UNION ALL
중복값도 다 포함한 결과를 반환
select 뒤에 distinct를 쓸때는 중복값을 제거하는 것처럼 all이 평소에 생략되어 있다고 생각하면 편하다.
MySQL은 지원하지 않는 기능
교집합: INTERSECT
→ INNER JOIN을 쓰면 된다
차집합: EXCEPT(MINUS -오라클)
→ LEFT JOIN을 쓰는 편 (, RIGHT JOIN)
합집합: FULL OUTER JOIN
→ LEFT JOIN, RIGHT JOIN을 UNION해서 사용
관련 문제 풀이
해커링크
african cities
select city.name
from city
INNER JOIN country on city.countrycode = country.code
where country.continent ="Africa"
Population Census
SELECT sum(city.population)
FROM city
INNER JOIN country on city.countrycode = country.code
WHERE country.continent = "Asia"
Average Population of Each Continent
SELECT country.continent, FLOOR(avg(city.population))
FROM CITY
INNER JOIN COUNTRY on city.countrycode = country.code
GROUP BY country.continent
리트코드
183. Customers Who Never Order
# Write your MySQL query statement below
select customers.name as Customers
from customers
left join orders on customers.id = orders.customerId
where orders.id is null
as로 이름 바꿔주는 것 주의!!!
UNION 문제 (난이도 상) - Symmetric Pairs (해커링크)
https://www.hackerrank.com/challenges/symmetric-pairs/problem?h_r=internal-search
SELECT X, Y
FROM functions
WHERE X = Y
GROUP BY X, Y
HAVING Count(*) > 1
UNION
SELECT f1.X, f1.Y
FROM functions as f1
INNER JOIN functions as f2 on f1.x = f2.y and f1.y = f2.x
WHERE f1.X < f1.Y
ORDER BY X
- UNION할때 select에서 가져오는 열 맞추기
- 셀프 조인 했을때는 ambiguous 하지 않게 Alias잘 지정하기
- ORDER BY는 맨 마지막에 한번만 쓰기