SQL

INNER JOIN (+ 해커랭크 예제)

얆생 2024. 10. 10. 17:05
  • JOIN이 필요한 이유

관계형 데이터베이스 RDBMS에서 데이터를 더 효율적으로 관리하기 위함

테이블을 따로 두고, 같은 값이 중복되지 않게

 

ex) 유저 아이디, 연락처, 배송 주소, 구매 상품, 상품 가격, 구매 개수 등이 쭉 나열되어 있음

아이디 연락처 주소 구매 상품 가격 개수 결제 수단
A 010-****-1111 영등포구 여의도동 NULL NULL NULL NULL
B 010-****-2222 송파구 석촌동 샴푸 5000 1 국민카드
B 010-****-2222 송파구 석촌동 식빵 6000 1 계좌이체
B 010-****-2222 송파구 석촌동 티백 8000 4 국민카드
B 010-****-2222 송파구 석촌동 냄비 7000 1 우리카드

 

B라는 고객은 구매 횟수가 많아서 아이디, 연락처, 주소 등이 계속 중복됨

이런식으로 한 테이블에 무수히 많은 데이터가 있으면 가독성이 떨어짐

 

테이블을 따로 두면

 

Users

ID 로그인 아이디 연락처 주소
1 A 010-****-1111 영등포구 여의도동
2 B 010-****-2222 송파구 석촌동

 

Orders

UserID 구매 상품 가격 개수 결제 수단
2 샴푸 5000 1 국민카드
2 식빵 6000 1 계좌이체
2 티백 8000 4 국민카드
2 냄비 7000 1 우리카드

 

윗 테이블의 보라색 영역이 사라지고 좀 더 효율적으로 데이터를 관리할 수 있음

 

 

나눠진 두 테이블을 합치려면 Users 테이블의 ID와 Orders 테이블의 UserID를 기준으로 연결

 

 

https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_join

  • INNER JOIN

엑셀의 inner join이랑 개념은 동일

교집합만 출력해줌

SELECT *
FROM 테이블1
     INNER JOIN 테이블2 ON (join의 기준이 되는 칼럼 ? = ?)

 

 

1. Customers와 Orders 테이블 CustomerID 기준으로 조인하기

 

SELECT *
FROM Orders
     INNER JOIN Customers ON Customers.CustomerID = Orders.CustomerID

 

만약 Customers 테이블에는 1이라는 CustomerID가 있는데, Orders 테이블에는 1이 없으면 연결 기준이 사라지므로 해당 열은 출력 안됌

 

 

 

2. ShipperID로 join을 한번 더 하고 싶으면 이어서 써주기

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

 

 

 

3. 테이블마다 쓰는 칼럼명이 다르다면?

 

ex) Customers 테이블에선 CustomerID인데, Orders에서는 id인 경우

     >> 현업에서는 이런 경우가 더 흔하다. 테이블을 설계하는 사람이 한 명이 아니기도 하고, 서비스를 개편할 때마다 이름이 계속 달라지기 때문에

 

+) ERD (Entity Relationship Diagram) :데이터베이스 설계 과정에서 사용되는 모델링 기법 중 하나로, 데이터베이스에 저장될 데이터 엔티티(entity)들과 엔티티 간의 관계(relationship)를 시각적으로 표현한다.

 

>> 이 내용은 나중에 더 보충

 

 

  • 해커랭크 예제 풀이 1

https://www.hackerrank.com/challenges/african-cities/problem?isFullScreen=true

 

African Cities | HackerRank

Query the names of all cities on the continent 'Africa'.

www.hackerrank.com

Given the CITY and COUNTRY tables, query the names of all cities where the CONTINENT is 'Africa'.

Note: CITY.CountryCode and COUNTRY.Code are matching key columns.

Input Format

The CITY and COUNTRY tables are described as follows:

 

풀이 접근

1. query the names of all cities >> 모든 데이터 다 필요한게 아니라 city의 name만 필요함

2. 두 테이블을 컨트리코드를 기준으로 연결 >> inner join
3. 근데 country 테이블에서는 continent가 Afica인 것만 출력 >> where문

 

SELECT name
FROM city
     INNER JOIN country ON city.countrycode = country.code
WHERE country.continent = 'Africa'

 

>> 이렇게 실행시키면 에러가 남

Error (stderr)
  • ERROR 1052 (23000) at line 1: Column 'name' in field list is ambiguous

ambiguous한 이유: city에도 country에도 name이란 칼럼이 있기 때문에

 

따라서, 어느 테이블의 name인지 명시해줘야함

 

최종 코드

SELECT city.name 
FROM city
     INNER JOIN country ON CITY.CountryCode = COUNTRY.Code
WHERE country.continent = 'Africa'

 

 

 

  • 해커랭크 예제 풀이 2

 

https://www.hackerrank.com/challenges/asian-population/problem?isFullScreen=true

 

Population Census | HackerRank

Query the sum of the populations of all cities on the continent 'Asia'.

www.hackerrank.com

Given the CITY and COUNTRY tables, query the sum of the populations of all cities where the CONTINENT is 'Asia'.

Note: CITY.CountryCode and COUNTRY.Code are matching key columns.

Input Format

The CITY and COUNTRY tables are described as follows:

 

풀이 접근

1. city와 country 테이블 code를 기준으로 조인 >> inner join

2. country에서 continent가 Asia인 모든 도시 >> where문 조건에 들어가기

3. 2번의 population sum을 출력 >> sum 사용

 

최종 코드

SELECT SUM(city.population)
FROM city
     INNER JOIN country ON city.countrycode = country.code
WHERE country.continent = 'Asia'

 

 

 

  • 해커랭크 예제 풀이 3 (JOIN 안 씀)

https://www.hackerrank.com/challenges/average-population/problem?isFullScreen=true

 

Average Population | HackerRank

Query the average population of all cities, rounded down to the nearest integer.

www.hackerrank.com

Query the average population for all cities in CITY, rounded down to the nearest integer.

Input Format

The CITY table is described as follows:

 

풀이 접근

1. city 테이블의 모든 도시의 인구 평균 >> AVG
2. 내림해서 정수로 만들기 >>  floor, 소수점 첫 번째 자리에서

 

SELECT FLOOR(AVG(population))
FROM city

 

 

 

  • 해커랭크 예제 풀이 4

https://www.hackerrank.com/challenges/average-population-of-each-continent/problem?isFullScreen=true

 

Average Population of Each Continent | HackerRank

Query the names of all continents and their respective city populations, rounded down to the nearest integer.

www.hackerrank.com

Given the CITY and COUNTRY tables, query the names of all the continents (COUNTRY.Continent) and their respective average city populations (CITY.Population) rounded down to the nearest integer.

Note: CITY.CountryCode and COUNTRY.Code are matching key columns.

Input Format

The CITY and COUNTRY tables are described as follows:

 

풀이 접근

1. city랑 country 테이블 연결 >> inner join

2. 밑처럼 continent 이름도 나와야 하고 각 continent마다 내림해서 정수로 만든 평균 인구수도 나와야 함 >> group by

3. group by에 쓴건 select에도 똑같이 써줘야 함, 집계 함수도 나란히

대륙 이름 평균 인구수
Asia ~~
   

 

최종 코드

SELECT country.continent
       , FLOOR(AVG(city.population))
FROM city
     INNER JOIN country ON city.countrycode = country.code
GROUP BY country.continent

 

 

 

 

처음부터 완벽하게 작성 못하니까 우선 베이스 코드 짜놓고 다시 생각하고, 하나씩 수정해나가기