BananMoon / SQL-Practice

It is Study Place to practice SQL.
0 stars 0 forks source link

JOIN (INNER, LEFT, SELF) + LeetCode 문제풀이 #4

Open BananMoon opened 1 month ago

BananMoon commented 1 month ago

RDB와 JOIN

하나의 테이블에 데이터들을 저장하다보면 Null값이 저장됨으로써 공간이 낭비되거나 동일한 값이 중복되는 공간 낭비가 발생하게 된다.

이럴 경우 두 개의 테이블로 분리하고, 두 테이블을 연결할 수 있는 값을 부여하는 방식으로 공간의 낭비를 제거할 수 있다. -> 이러한 아이디어에서 나온 것이 Relational Data Base (RDB)이다.

테이블 간에 관계가 있기 때문에, JOIN은 불가피한 작업이다.

예시 테이블

만약 아래와 같은 SQL문을 작성하게 되면? 카티산 제곱이라는, 방식이 수행된다.

  1. Users 데이터와 Orders 데이터의 모든 경우의 수만큼 데이터를 만들어 준 후에!
  2. WHERE 절에 따라 조건문으로 필터링을 건다.
    SELECT *
    FROM Users, Orders
    WHERE Users.id = Orders.userId;

    이렇게 하는 방식은 매우 비효율 적. 그래서 INNER JOIN이라는 예약어를 사용한다.

INNER JOIN

양 쪽 테이블에 모두 존재하는 데이터(교집합)만 출력한다.

SELECT *
FROM Users
INNER JOIN Orders 
ON Users.id = Orders.userId;

추가

INNER JOIN을 해서 연관된 다른 테이블이 또 있다면, INNER JOIN을 연달아 사용할 수도 있다.

SELECT * 
FROM Customers
INNER JOIN Orders ON Customers.customerID = Orders.customerID
INNER JOIN Shippers ON Orders.ShipperID = Shippers.ShipperId

LEFT JOIN

Users와 Orders 테이블이 있을 때, INNER JOIN을 하게 되면 주문을 한 사용자만 조회된다. 주문을 한번도 하지 않은 사용자도 함께 조회되도록 해달라는 요구사항이 있다면, LEFT JOIN을 사용할 수 있다.

SELECT *
FROM Users
LEFT JOIN Orders
ON Users.userId = Orders.userId

LEFT JOIN의 두 테이블의 위치를 바꾸면 RIGHT JOIN과 동일하기 때문에 실무에서는 혼동을 방지하는 차원에서 LEFT JOIN을 주로 사용하고, RIGHT JOIN은 거의 사용하지 않는다. Ex) A LEFT JOIN B == B RIGHT JOIN A

참고하기 좋은 View 사이트

BananMoon commented 1 month ago
  1. Afrian Cities

    SQL문

    MySQL

    SELECT CITY.NAME
    FROM CITY
    INNER JOIN COUNTRY
    ON CITY.COUNTRYCODE = COUNTRY.CODE
    WHERE COUNTRY.CONTINENT = 'Africa';
BananMoon commented 1 month ago
  1. Asian Population

    SQL문

    MySQL

    SELECT SUM(CITY.POPULATION)
    FROM CITY
    INNER JOIN COUNTRY
    ON CITY.COUNTRYCODE = COUNTRY.CODE
    WHERE COUNTRY.CONTINENT = 'Asia';
BananMoon commented 1 month ago
  1. Average Population of Each Continent

    SQL문

    MySQL

    SELECT country.continent, FLOOR(AVG(city.population))
    FROM city
    INNER JOIN country
    ON city.countrycode = country.code
    GROUP BY country.continent;
BananMoon commented 1 month ago

LEFT JOIN 문제

  1. Customers who never order

LEFT JOIN 테이블에 대해 ON 절로 id값을 비교했는데, 우측 테이블 (Orders)에 데이터가 없다고 조회되지 않는 것이 아니라 Null 로 값이 채워져서 조회된다. 그러므로 Orders 테이블에 없는, 즉 한번도 주문하지 않은 회원만 조회되도록 하기 위해서는 WHERE orders.id is null을 추가해줘야 한다.

SELECT customers.name AS Customers
FROM customers
LEFT JOIN orders
ON customers.id = orders.customerId
WHERE orders.id is null;
BananMoon commented 1 month ago

SELF JOIN 문제

코딩테스트에 자주 등장하는 유형

  1. Employees earning more than their managers

동일한 테이블을 두개로 해서 JOIN할건데, 이때 기준은 employeeId로 한다.

SQL

MySQL

SELECT employee.name AS Employee
FROM employee
INNER JOIN employee AS manager
ON employee.managerId = manager.id
WHERE employee.salary > manager.salary;
BananMoon commented 1 month ago
  1. [Rising Temperature]()

조건

BananMoon commented 4 weeks ago

아래 SQL을 수행하면, 주문을 하지 않은 회원, 주문을 한 회원이 모두 조회될 것이다.

SELECT *
FROM Customers
LEFT JOIN Orders ON Customer.id = Orders.custmorId

그런데 주문은 했지만 회원이 아닌 데이터 (즉, Orders 테이블에만 존재하고 Customers 테이블에 존재하지 않는 데이터)도 함께 조회하고자 한다면?

즉, 합집합을 구하고자 하는 건데 이럴 때에는 FULL OUTER JOIN을 사용하면 된다. MySQL에서는 FULL OUTER JOIN을 사용하지 못하기 때문에 아래와 같이 LEFT JOIN과 RIGHT JOIN을 섞어서 사용해야 한다.

FULL OUTER JOIN : LEFT JOIN과 RIGHT JOIN을 함께 사용한다. (MySQL 편)

합칠 때는 UNION을 사용한다.

SELECT *
FROM Customers
LEFT JOIN Orders ON Customer.id = Orders.custmorId
UNION
SELECT *
FROM Customers
RIGHT JOIN Orders ON Customers.id = Orders.CustomerId
BananMoon commented 3 weeks ago
  1. Symmetric Pairs
    • x, y가 동일한 값들과 x, y를 뒤집으면 동일한 값들 데이터를 구분지어서 구한 후에 UNION으로 합쳐준다.
    • x=y select 문을 구할 때는 Symmetric Pairs가 되려면, 두쌍씩 있어야 하니 group by 결과가 2 이상이어야 함.
    • f1.x=f2.y and f1.y=f2.x 인 데이터를 구할 때는 x가 y보다 작은 케이스만 출력되되게 하면 되므로 조건절을 추가한다.
    • UNION 완료 후에 테이블 전체에 대해서 order by를 적용한다.
    • ORDER BYUNION 기준으로 뒤에 있는 구문 끝에만 작성할 수 있다.⚡️
SELECT x,y FROM functions
WHERE x = y
GROUP BY x, y
HAVING count(*) >=2

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;

풀이 후기 Symmetric Pairs 케이스를 두 케이스로 나눠서 구하는 방법으로 생각을 못해서 헤맸다.