👩🏻‍💻직무/SQL STUDY

[SQL Study] 쿼리 '잘' 짜는 PO되기 / INNER JOIN (Feat. 인프런-중급)

Kailyim 2021. 8. 26. 23:26

PO라는 직무를 하면서 전략을 짜는 것도 어려웠지만, 요즘 제일 어려운 것을 꼽으라면 직접 쿼리를 짜는 것이라고 말할 수 있을 것 같다. 쿼리로 고통 받고 있는데 이것도 다 나의 가치를 높여준다라는 생각으로 별도로 강의도 끊어서 보고, 쿼리도 직접 짜보고 있는데 생각보다 시간이 많이 걸린다. 

 

인프런에서 초급, 중급, 고급 강의와 문제풀이 강의까지 결제하고(물론 자기계발비 찬스로^^) 세워라 내워라 듣고 있는데 

강의를 볼 수 있는 시간이 단 7일 밖에 남지 않아서 오늘부터 하루에 13강씩 매일 6시간을 투자해서 들어야만 한다.

 

강의 듣는데만 6시간이니, 실제 문제풀이 해설을 듣기 전 쿼리를 짜는 시간까지 합치면 매일 밤 늦게 까지 쿼리를 짜야한다 이말씀. 이렇게 호다닥 듣게되면 나중에 기억 못할 것 같아서 간단하게 기록을 하려고 SQL 관련 첫 포스팅을 작성했다. 

 

일주일동안 빡세게 다 듣고나면, 과연 나는 쿼리 고수가 되어 있을 것인가! 

 


INNER JOIN 

  • 문제 풀이 해설을 듣기 전 내가 먼저 풀어보고, 어떤 부분이 헷갈려서 풀지 못했는지 혹은 틀렸는지에 대해 간단히 작성하려고 한다. 
  • 문제 - 해커랭크 African Cities
    • 더보기
      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.

✍🏻 첫번째 쿼리를 작성할 땐 아래와 같은 코드로 작성했다. 

SELECT 
    country.name
FROM CITY
    INNER JOIN Country ON city.countrycode=country.code
where country.continent = 'Africa'

그러자 Wrong Answer :( 라는 결과가 나왔는데, 결과는 아래 테이블 처럼 나왔다.

뭔가 잘못되었다는 건 알겠는데, 정확하게 뭐가 잘못 되었는지는 알 수 없었다. 

SELECT
    Case
         WHEN COUNTRY.CONTINENT = 'Africa' THEN Country.Name OR City.Name END AS NAME
FROM CITY
    INNER JOIN COUNTRY ON CITY.CountryCode = COUNTRY.Code

쿼리를 위와 같이 수정해봤다. 

OMG  :< 

더 이상하게 나왔다. 일단 남은 강의가 많아서 바로 해설을 봤다. 

알고보니 첫번째 짰던 쿼리에서 SELECT 문에 country.name을 city.name으로 바꾸기만 하면 되는 부분이었다.

사실 country 테이블에도 name이 있었고, city 테이블에도 name이 있어서 어떤 name을 출력하라는 건지 헷갈렸다.

 

문제에 'query the names of all cities' 라고 적혀있으니, City name을 출력했으면 되는 간단한 건이었는데 

이런 소소한 부분을 놓쳤다. 

 

정답

SELECT 
    city.name
FROM CITY
    INNER JOIN Country ON city.countrycode=country.code
where country.continent = 'Africa'

첫번째 문제의 해설을 들은 뒤, INNER JOIN 관련 두 번째 문제를 풀었다.

더보기

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

1번 문제 해설을 듣고 나니, 이번 문제는 어떻게 풀어야하는지 감이 왔다. 

문제를 보니 CITY와 COUNTRY 테이블을 INNER JOIN 하고, CONTINENT가 'Asia'인 모든 도시의 Population의 합을 구하는 문제였다.  문제 안에 답이 있으니 쿼리를 있는 그대로 작성해봤다.

SELECT 
    SUM(CITY.population)
FROM CITY
    INNER JOIN COUNTRY ON CITY.CountryCode = COUNTRY.Code
WHERE COUNTRY.CONTINENT = 'Asia'

헤헿 풀자마자 정답이라고 나오니 '이 맛에 개발자 하는건가' 싶은 생각이 들었다 (easy 문제 풀고 허세 부리는 것 보소..)

 

자 그럼 INNER JOIN을 연습할 수 있는 마지막 문제.

더보기

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.

음, CITY 와 COUNTRY 테이블을 조인하고 모든 Continent의 이름을 출력하고, 도시 인구 각각의 평균을 구하고 rounded down하여 정수값을 만들라는 읽기만 해도 어려워서 엄두가 나지 않는 문제였다. 

일단 짜봤다. 

 

SELECT
    Country.Continent
    , TRUNCATE(AVG (city.population),-1)
FROM CITY
    INNER JOIN COUNTRY ON CITY.CountryCode = COUNTRY.Code
GROUP BY Country.Continent

위 처럼 코드를 짰는데 아래와 같은 결과가 나왔다. 

Continent의 이름과 각 도시별 인구 평균 뽑는 결과로 잘 나온 것 같은데 왜 틀렸는지 도통 모르겠네.

SELECT 문에 Country.continent가 잘못된 걸까? City로 바꿔보자. 

응 아니야~ 응 또 틀렸어~

LEFT JOIN인가..? WHERE절이 들어가야하나 아주 고민에 고민을 하다가 결국 해설 ㄱ ㄱ 

 

정답

SELECT
    country.continent
    , FLOOR(AVG (city.population))
FROM CITY
     INNER JOIN COUNTRY ON CITY.CountryCode = COUNTRY.Code
GROUP BY country.continent

헐.. 너무나 어이없게도 숫자 버림하는데 FLOOR안쓰고, TRUNCATE 함수 썼다고 틀린 거였다... 

솔직히 2개 각각 뭐가 다른지 몰라서 일단 구글링을 해서 찾은 결과

  • TRUNC()
    • 숫자값을 특정 위치에서 절삭한 후 리턴
  • FLOOR()
    • 숫자값을 소숫점 첫째자리에서 절삭하여 정수값으로 리턴

아무래도 문제에 Integer 정수값으로 리턴하라고해서, TRUNC 함수를 오답처리 한  것 같은 뇌피셜..

업무할땐 TRUNC와 FLOOR 둘 중 아무거나 사용해도 될 것 같은 느낌적인 느낌이 든다.

 

오늘의 코드 스터디는 끝.

 

내일도 정시 퇴근하고, 호다닥 강의들어야겠다. 생각보다 졸잼.. 👻

반응형