#1 Bigger than Russia
러시아의 인구를 가져와서 모든 나라의 인구와 비교, 러시아 인구수 보다 크면 name 데이터 출력
SELECT name
FROM world
WHERE population > (SELECT population
FROM world
WHERE name='Russia')
#2 Richer than UK
영국의 인당 GDP값을 가져와서 대륙이 유럽인 나라의 인당 GDP 값과 비교 영국 보다 크면 name 데이터 출력
SELECT name
FROM world
WHERE continent = 'Europe' AND
gdp/population > (SELECT gdp/population
FROM world
WHERE name = 'United Kingdom')
#3 Neighbours of Argentina and Australia
아르헨티나와 호주가 포함 된 대륙과 같은 대륙인 나라의 이름과 대륙을 출력한다.
서브 쿼리의 선택된 continent값이 두개이기에 IN을 사용해야 한다. =을 사용하면 안된다.
이름 순으로 정렬한다.
SELECT name, continent
FROM world
WHERE continent IN (SELECT continent
FROM world
WHERE name IN ('Argentina','Australia'))
ORDER BY name
#4 Between Canada and Poland
캐나다 인구수보다 크고 폴란드 인구수보다 작은 나라의 이름과 인구수를 출력한다.
SELECT name, population
FROM world
WHERE population > (SELECT population
FROM world
WHERE name = 'Canada') AND
population < (SELECT population
FROM world
WHERE name = 'Poland')
#5 Percentages of Germany
유럽 대륙의 모든 나라를 독일의 인구수로 나눈 인구수 값에 백분률을 해주고, 반올림을 해준다. 그 값이 %를 붙여 준다.
ROUND함수로 반올림을 하고, CONCAT함수로 문자를 덧붙인다.
SELECT문에 서브 쿼리를 사용한다.
SELECT name, CONCAT(ROUND(population/(SELECT population
FROM world
WHERE name = 'Germany')*100,0),'%')
FROM world
WHERE continent = 'Europe'
#6 Bigger than every country in Europe
유럽의 모든 나라의 GDP를 비교해 보고 그것보다 높은 나라의 이름을 출력한다.
ALL을 사용해서 서브쿼리의 모든 데이터 값을 비교해서 참일 경우를 판단한다.
만약 ALL을 붙이지 않는다면 서브쿼리의 선택된 값들은 여러개 이므로 10 > (1, 2, 3, 4, 5, 6, 7) 이렇게 되는데 옳지 않은 문법이다. 10 > ALL(1, 2, 3, 4, 5, 6, 7) 이렇게 해주어야 한다.
서브쿼리 앞에 붙이는 것들은 IN, ANY, SOME, ALL, EXISTS 이렇게 있다.
SELECT name
FROM world
WHERE gdp > ALL(SELECT gdp
FROM world
WHERE gdp > 0 AND continent ='Europe')
#7 Largest in each continent
같은 대륙 내의 가장 큰 넓이 값을 가진 나라의 대륙과 이름과 넓이를 출력한다.
AS를 사용해서 메인 쿼리의 world -> x로 치환, 서브 쿼리의 world -> y로 치환한다. AS는 생략이 가능하다.
서브 쿼리에서 y의 대륙과 x의 대륙이 같은 나라의 넓이 값을 가져와 x의 넓이 값과 비교한다.
y의 모든 나라를 가져와서 비교해야하므로 ALL을 사용한다.
SELECT continent, name, area
FROM world x
WHERE area >= ALL(SELECT area
FROM world y
WHERE y.continent = x.continent AND area >0)
#8 First country of each continent (alphabetically)
같은 대륙 내 알파벳 순 제일 빠른 이름의 대륙과 이름을 출력한다.
서브 쿼리에서 같은 대륙의 이름 값을 가져오고 그 값을 메인 이름과 비교해서 제일 빠른 이름을 찾아낸다.
SELECT continent, name
FROM world x
WHERE name <= ALL(SELECT name
FROM world y
WHERE y.continent = x.continent)
#9 Difficult Questions
문제는 모든 국가의 인구가 25000000 미만인 대륙을 찾은 다음, 이 대륙과 관련된 국가의 이름을 찾는 것이다.
카리브해와 오세아니아 대륙만 25000000 미만이고 그 대륙에 포함된 나라의 이름을 출력하면 된다.
x의 대륙과 같은 대륙을 찾아내고 그 대륙의 나라의 모든 인구수를 비교한다.
이렇게 하면 x의 각 대륙의 모든 인구수를 비교할 수 있다. ALL은 AND조건을 거는 것과 같으므로.
25000000 >= ALL(유럽 나라1 인구수, 유럽 나라2 인구수, 유럽 나라3 인구수 ...) -> 통과 안됨
25000000 >= ALL(카리브해 나라1 인구수, 카리브해 나라2 인구수, 카리브해 나라3 인구수 ...) -> 카리브해 통과!
25000000 >= ALL(영국 나라1 인구수, 영국 나라2 인구수, 영국 나라3 인구수 ...) -> 통과 안됨
이런 식이다.
조금 복잡한 것 같다..
SELECT name, continent, population
FROM world AS x
WHERE 25000000 >= ALL(SELECT population
FROM world y
WHERE x.continent = y.continent
AND y.population>0)
#10 Difficult Questions
함정이 깊어서 좀 헤맸다. 9번 문제보다 이해는 더 쉬운 것 같다. 9번 문제는 뭐랄까. 무슨 소리하는지 모르겠는 느낌이었다. 이 문제는 같은 대륙의 나라의 인구수 3배 한 값보다 큰 나라를 출력하면 된다.
이웃 대륙이기 때문에 x.name과 y.name이 같으면 빼줘야 한다. 그렇지 않으면 러시아 인구 >= 러시아 인구 *3 이라는 말도 안되는 식의 조건을 걸게 되어 답이 출력되지 않는다.
SELECT name, continent
FROM world AS x
WHERE population >= ALL(SELECT population*3
FROM world y
WHERE x.continent = y.continent
AND y.population>0 AND x.name != y.name)
정리하기
서브쿼리를 사용하면 할 수록 반복문 느낌이 강하게 들었다. SELECT를 한번 하고 SELECT를 또 하면 이중 for문을 도는 것하고 비슷한 것 같다.
(SELECT 서브쿼리) : SELECT문, FROM문, WHERE문 등등에 사용할 수 있다.
IN : 리턴 값 중 하나라도 만족하면 참이다.
ALL : 리턴 값 모두를 만족해야 참이다.
ANY, SOME : 리턴 값 중 하나라도 만족하면 참이다.
EXISTS : 리턴 값 중 하나라도 만족하면 참이다.
AS : 치환
'프로그래밍 > MySQL' 카테고리의 다른 글
[MySQL] SQL ZOO JOIN 답 해설 (0) | 2021.02.21 |
---|---|
[MySQL] SQL ZOO SUM and COUNT 답 해설 (0) | 2021.02.20 |
[MySQL] SQL ZOO SELECT from Nobel 답 해설 (0) | 2021.02.19 |
[MySQL] SQL ZOO SELECT basics 답 해설 (0) | 2021.02.18 |
[MySQL] 프로그래머스 SQL String, Date 답 해설 (0) | 2021.02.17 |