I’ve just completed the sixth course in the Google Data Analytics program and wanted to sharpen my SQL skills before moving on to R. This repository contains my solutions and notes from working through the SQLZOO challenges.
- 1 SELECT basics
- 2 SELECT from World
- 3 SELECT from Nobel
- 4 SELECT within SELECT
- 5 SUM and COUNT
- 6 JOIN
- 7 More JOIN operations
- 8 Using Null
- 9 Self join
SELECT population
FROM world
WHERE name = 'Germany'
SELECT name, population
FROM world
WHERE name IN ('Sweden', 'Norway', 'Denmark')
SELECT name, area
FROM world
WHERE area BETWEEN 200000 AND 250000
SELECT name, continent, population
FROM world
2. Show the name for the countries that have a population of at least 200 million. 200 million is 200000000, there are eight zeros.
SELECT name FROM world
WHERE population >= 200000000
3. Give the name and the per capita GDP for those countries with a population of at least 200 million.
SELECT name,
gdp/population AS per_capita_GDP
FROM world
WHERE population >= 200000000
SELECT name, population/1000000 AS mil
FROM world
WHERE continent ="South America"
SELECT name, population
FROM world
WHERE name IN ("France","Germany","Italy")
SELECT name
FROM world
WHERE name LIKE "United%"
SELECT name, population, area
FROM world
WHERE area > 3000000
OR population > 250000000
8. Exclusive OR (XOR). Show the countries that are big by area (more than 3 million) or big by population (more than 250 million) but not both.
SELECT name, population, area
FROM world
WHERE area > 3000000
XOR population > 250000000
9. Show the name and population in millions and the GDP in billions for the countries of the continent 'South America'.
SELECT name, ROUND(population/1000000,2), ROUND(gdp/1000000000.0,2)
FROM world
WHERE continent="South America"
10. Show the name and per-capita GDP for those countries with a GDP of at least one trillion (1000000000000; that is 12 zeros).
SELECT name,ROUND(gdp/population,-3) AS per_capita_GDP
FROM world
WHERE gdp >=1000000000000
SELECT name, capital
FROM world
WHERE LENGTH(name)=LENGTH(capital)
12. Show the name and the capital where the first letters of each match. Don't include countries where the name and the capital are the same word.
SELECT name,capital
FROM world
WHERE LEFT(name,1)=LEFT(capital,1)
AND SUBSTR(name,2)<>SUBSTR(capital,2)
SELECT name
FROM world
WHERE name LIKe "%a%"
AND name LIKe "%e%"
AND name LIKe "%i%"
AND name LIKe "%o%"
AND name LIKe "%u%"
AND name NOT LIKe "% %"
SELECT yr, subject, winner
FROM nobel
WHERE yr = 1950
SELECT winner
FROM nobel
WHERE yr = 1962
AND subject = 'literature'
SELECT yr, subject
FROM nobel
WHERE winner = "Albert Einstein"
SELECT winner
FROM nobel
WHERE yr >= 2000
AND subject="peace"
5. Show all details (yr, subject, winner) of the literature prize winners for 1980 to 1989 inclusive.
SELECT yr, subject, winner
FROM nobel
WHERE yr BETWEEN 1980 AND 1989
AND subject="literature"
Theodore Roosevelt Thomas Woodrow Wilson Jimmy Carter Barack Obama
SELECT * FROM nobel
WHERE winner in ("Theodore Roosevelt",
"Thomas Woodrow Wilson",
"Jimmy Carter",
"Barack Obama")
SELECT winner FROM nobel
WHERE winner LIKE "John%"
8. Show the year, subject, and name of physics winners for 1980 together with the chemistry winners for 1984.
SELECT yr,subject,winner
FROM nobel
WHERE yr="1980"
AND subject="physics"
UNION
SELECT yr,subject,winner
FROM nobel
WHERE yr="1984"
AND subject="chemistry"
SELECT yr, subject, winner
FROM nobel
WHERE yr=1980
AND subject <> "chemistry"
AND subject <> "medicine"
10. Show year, subject, and name of people who won a 'Medicine' prize in an early year (before 1910, not including 1910) together with winners of a 'Literature' prize in a later year (after 2004, including 2004).
SELECT yr,subject,winner
FROM nobel
WHERE yr<1910
AND subject="Medicine"
UNION
SELECT yr,subject,winner
FROM nobel
WHERE yr>=2004
AND subject="Literature"
SELECT *
FROM nobel
WHERE winner="PETER GRĂśNBERG"
SELECT *
FROM nobel
WHERE winner="EUGENE O'NEILL"
13. List the winners, year and subject where the winner starts with Sir. Show the the most recent first, then by name order.
SELECT winner,yr,subject
FROM nobel
WHERE winner LIKE "Sir%"
ORDER BY yr DESC, winner
14. Show the 1984 winners and subject ordered by subject and winner name; but list chemistry and physics last.
SELECT winner, subject
FROM nobel
WHERE yr=1984
ORDER BY subject IN ('physics','chemistry'),subject
SELECT name
FROM world
WHERE population >(SELECT population FROM world WHERE name='Russia')
SELECT name
FROM world
WHERE gdp/population >
(SELECT gdp/population FROM world
WHERE name='United Kingdom')
AND continent="Europe"
3. List the name and continent of countries in the continents containing either Argentina or Australia. Order by name of the country.
SELECT name,continent
FROM world
WHERE continent ="Oceania" OR continent ="South America"
ORDER BY name
4. Which country has a population that is more than United Kingdom but less than Germany? Show the name and the population.
SELECT name, population
FROM world
WHERE population > (SELECT population FROM world WHERE name="United KIngdom")
AND population < (SELECT population FROM world WHERE name="Germany")
5. Show the name and the population of each country in Europe. Show the population as a percentage of the population of Germany.
SELECT name,CONCAT(ROUND(((population/(SELECT population FROM world WHERE name="Germany"))*100),0),"%") AS percentage
FROM world
WHERE continent="Europe"
SELECT name
FROM world
WHERE gdp > (SELECT MAX(gdp)
FROM world
WHERE continent="Europe")
SELECT continent, name, area FROM world x
WHERE area >= ALL (SELECT area FROM world y
WHERE y.continent=x.continent)
SELECT continent, name FROM world x
WHERE name <= ALL (SELECT name FROM world y
WHERE y.continent=x.continent)
9. Find the continents where all countries have a population <= 25000000. Then find the names of the countries associated with these continents. Show name, continent and population.
SELECT name, continent, population
FROM world x
WHERE 25000000 >= ALL (SELECT population FROM world y WHERE x.continent=y.continent)
10. Some countries have populations more than three times that of all of their neighbours (in the same continent). Give the countries and continents.
SELECT name, continent
FROM world x
WHERE population > ALL (SELECT population*3 FROM world y WHERE x.continent=y.continent AND x.name!=y.name)
SELECT SUM(population)
FROM world
SELECT DISTINCT continent
FROM world
SELECT SUM(gdp)
FROM world
WHERE continent="Africa"
SELECT COUNT(name)
FROM world
WHERE area >= 1000000
SELECT SUM(population)
FROM world
WHERE name IN ('Estonia', 'Latvia', 'Lithuania')
SELECT continent, COUNT(continent) number_of_countries
FROM world
GROUP BY continent
7. For each continent show the continent and number of countries with populations of at least 10 million.
SELECT continent, COUNT(continent) number_of_countries
FROM world
WHERE population >= 10000000
GROUP BY continent
SELECT continent
FROM world
GROUP BY continent
HAVING SUM(population) >= 100000000
SELECT matchid, player
FROM goal JOIN game ON(id=matchid)
WHERE teamid="GER"
SELECT DISTINCT id,stadium,team1,team2
FROM game JOIN goal ON(matchid=id)
WHERE ID="1012"
SELECT player,teamid,stadium,mdate
FROM game JOIN goal ON (id=matchid)
Where teamid="GER"
SELECT team1,team2,player
FROM game JOIN goal ON (id=matchid)
Where player LIKE 'Mario%'
SELECT player, teamid, coach, gtime
FROM goal JOIN eteam on teamid=id
WHERE gtime<=10
6. List the dates of the matches and the name of the team in which 'Fernando Santos' was the team1 coach.
SELECT mdate, teamname
FROM game JOIN eteam ON (game.team1=eteam.id)
WHERE coach="Fernando Santos"
7. List the player for every goal scored in a game where the stadium was 'National Stadium, Warsaw'.
SELECT player
FROM game JOIN goal ON(id=matchid)
WHERE stadium="National Stadium, Warsaw"
SELECT DISTINCT player
FROM game JOIN goal ON matchid = id
WHERE ((team1='GER' AND team2!="GER") OR (team1!='GER' AND team2="GER")) AND teamid!="GER"
SELECT teamname, COUNT(teamname)
FROM goal JOIN eteam ON (goal.teamid=eteam.id)
GROUP BY teamname
SELECT stadium, COUNT(1)
FROM game JOIN goal ON matchid=id
GROUP BY stadium
SELECT matchid,mdate,COUNT(teamid)
FROM game JOIN goal ON matchid=id
WHERE teamid="POL" OR team1="POL" OR team2="POL"
GROUP BY matchid,mdate
12. For every match where 'GER' scored, show matchid, match date and the number of goals scored by 'GER'.
SELECT matchid,mdate,COUNT(teamid)
FROM game JOIN goal ON matchid=id
WHERE teamid="GER"
GROUP BY matchid,mdate
SELECT
mdate,
team1,
SUM(CASE WHEN teamid = team1 THEN 1 ELSE 0 END) AS score1,
team2,
SUM(CASE WHEN teamid = team2 THEN 1 ELSE 0 END) AS score2
FROM game
LEFT JOIN goal ON matchid = id
GROUP BY mdate, matchid, team1, team2
SELECT id, title
FROM movie
WHERE yr=1962
SELECT yr
FROM movie
WHERE title="Citizen Kane"
3. List all of the Star Trek movies, include the id, title and yr (all of these movies include the words Star Trek in the title). Order results by year.
SELECT id, title,yr
FROM movie
WHERE title LIKE "%Star Trek%"
ORDER BY yr
SELECT DISTINCT actor.id
FROM casting JOIN actor ON casting.actorid=actor.id
WHERE actor.name="GLenn Close"
SELECT id
FROM movie
WHERE title= 'Casablanca'
SELECT actor.name
FROM actor JOIN casting ON actor.id=casting.actorid
WHERE movieid=11768
SELECT actor.name
FROM casting JOIN actor ON actor.id=casting.actorid
JOIN movie ON casting.movieid=movie.id
WHERE title="Alien"
SELECT movie.title
FROM casting JOIN actor ON casting.actorid=actor.id
JOIN movie ON casting.movieid=movie.id
WHERE actor.name='Harrison Ford'
SELECT movie.title
FROM casting JOIN actor ON casting.actorid=actor.id
JOIN movie ON casting.movieid=movie.id
WHERE actor.name='Harrison Ford' AND casting.ord!=1
SELECT movie.title, actor.name
FROM casting JOIN actor ON casting.actorid=actor.id
JOIN movie ON casting.movieid=movie.id
WHERE movie.yr=1962 AND casting.ord=1
11. Which were the busiest years for 'Rock Hudson', show the year and the number of movies he made each year for any year in which he made more than 2 movies.
SELECT yr,COUNT(title) FROM
movie JOIN casting ON movie.id=movieid
JOIN actor ON actorid=actor.id
WHERE name='Rock Hudson'
GROUP BY yr
HAVING COUNT(title) > 2
SELECT DISTINCT movie.title, actor.name
FROM casting JOIN movie ON casting.movieid=movie.id JOIN actor ON casting.actorid=actor.id
WHERE movie.id IN (10016,
12354,12497,12766,13846,15145,15476,16870,17117,17445,17765,18270,20136,20136,20180,20181,20509,20627,21023,21154,21171,21483) AND casting.ord=1
SELECT name FROM teacher WHERE dept IS NULL
SELECT teacher.name, dept.name
FROM teacher INNER JOIN dept
ON (teacher.dept=dept.id)
SELECT teacher.name, dept.name
FROM teacher LEFT JOIN dept ON (teacher.dept=dept.id)
SELECT teacher.name, dept.name
FROM teacher RIGHT JOIN dept ON (teacher.dept=dept.id)
5. Use COALESCE to print the mobile number. Use the number '07986 444 2266' if there is no number given. Show teacher name and mobile number or '07986 444 2266'.
SELECT name, COALESCE(mobile,"07986 444 2266")
FROM teacher
6. Use the COALESCE function and a LEFT JOIN to print the teacher name and department name. Use the string 'None' where there is no department.
SELECT teacher.name, COALESCE(dept.name,"None")
FROM teacher LEFT JOIN dept on teacher.dept=dept.id
SELECT COUNT(name),COUNT(mobile)
FROM teacher
8. Use COUNT and GROUP BY dept.name to show each department and the number of staff. Use a RIGHT JOIN to ensure that the Engineering department is listed.
SELECT dept.name, COUNT(teacher.name)
FROM teacher RIGHT JOIN dept ON teacher.dept=dept.id
GROUP BY dept.name
9. Use CASE to show the name of each teacher followed by 'Sci' if the teacher is in dept 1 or 2 and 'Art' otherwise.
SELECT teacher.name,
CASE WHEN teacher.dept IN(1) OR teacher.dept IN (2)
THEN "Sci"
ELSE "Art"
END
FROM teacher
10. Use CASE to show the name of each teacher followed by 'Sci' if the teacher is in dept 1 or 2, show 'Art' if the teacher's dept is 3 and 'None' otherwise.
SELECT teacher.name,
CASE WHEN teacher.dept IN(1) OR teacher.dept IN (2)
THEN "Sci"
WHEN teacher.dept IN(3)
THEN "Art"
ELSE "None"
END
FROM teacher
SELECT COUNT(*)
FROM stops
SELECT id
FROM stops
WHERE name="Craiglockhart"
SELECT stops.id, stops.name
FROM stops JOIN route ON stops.id=route.stop
WHERE route.num="4" AND route.company="LRT"
SELECT company, num, COUNT(*)
FROM route WHERE stop=149 OR stop=53
GROUP BY company, num
HAVING COUNT(*)=2