SQLZOO笔记(一)

Basic key words: SELECT, FROM, WHERE, IN, BETWEEN AND, AS, LIKE...


The world table-(name, continent, area, population, gdp, capital, tld, flag)

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.
Show name, population and area.

SELECT name, population, area FROM world
WHERE area>=3000000 XOR population>=250000000

Find the country that has all the vowels and no spaces in its name. You can use the phrase name NOT LIKE '%a%' to exclude characters from your results.

Equatorial Guinea and Dominican Republic have all of the vowels (a e i o u) in the name. They don't count because they have more than one word in the name.

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 嵌套用法

1.Using the result of SELECT as index
List each country in the same continent as 'Brazil'.

SELECT name FROM world
WHERE continent = (SELECT continent 
                   FROM world WHERE name = 'Brazil')

2.Subquery returns multiple results
In this case: ('North America' and 'South America')

SELECT name, continent FROM world
WHERE continent IN (SELECT continent 
                    FROM world WHERE name='Brazil'
                                  OR name='Mexico')

3.Subquery(multiple results) with operators
Key words: ALL/ANY

SELECT name FROM world
WHERE population > ALL (SELECT population FROM world
                        WHERE continent='Europe')

4.Subquery on the SELECT line
Only one value should be returned from subquery.

SELECT population/(SELECT population FROM world WHERE name='United Kingdom') FROM world
WHERE name = 'China'

SELECT嵌套的延申:Correlated Subquery - we can refer to values in the outer SELECT within the inner SELECT.
Find the largest country (by area) in each continent, show the continent, the name and the area.

SELECT continent, name, area FROM world x  # 给内外表命名作为区分
WHERE area >= ALL (SELECT area FROM world y
                   WHERE y.continent=x.continent  # where the continent is the same
                   AND area > 0)

A correlated subquery works like a nested loop: the subquery only has access to rows related to a single record at a time in the outer query. The technique relies on table aliases to identify two different uses of the same table, one in the outer query and the other in the subquery.

ENHANCEMENT: List each continent and the name of the country that comes first alphabetically.

SELECT continent, name FROM world x
WHERE name = (SELECT name FROM world y
              WHERE x.continent = y.continent  # 一个continent循环完了之后进入下一个
              ORDER BY name LIMIT 1)
# 以下为错误写法
SELECT continent, name FROM world x
WHERE name IN (SELECT name FROM world y
               WHERE x.continent = y.continent
               ORDER BY name LIMIT 1)

ENHANCEMENT: 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
                       AND population > 0)

ENHANCEMENT: Some countries have populations more than three times that of any of their neighbors(in the same continent). Give the countries and continents.

SELECT name, continent FROM world x
WHERE population > ALL (SELECT 3*population FROM world y
                        WHERE x.continent=y.continent
                        AND population > 0
                        AND x.name <> y.name)

总结:适用于在某一维度内(continent)使用特定规则进行选择
对比:

#  Show the countries with a greater GDP than any country in Africa
SELECT name FROM bbc
WHERE gdp > (SELECT MAX(gdp) FROM bbc WHERE region = 'Africa')
# 规则为gdp大于region维度下Africa水平的gdp,而非在region维度内的筛选

Show the name and the population of each country in Europe. Show the population as a percentage of the population of Germany.
CONCAT(s1, s2 ...)

SELECT name, CONCAT(ROUND(100*population/(SELECT population 
                                          FROM world WHERE name = 'Germany')),'%') FROM world
WHERE continent = 'Europe'
name CONCAT(ROUND(...
Albania 3%
Andorra 0%
Austria 11%
... ...
Germany 100%
... ...

GROUP BY 和 HAVING 用法

  1. When GROUP BY, all the other columns must be aggregated by aggregate functions.
  2. The WHERE clause filters rows before the aggregation, the HAVING clause filters after the aggregation.

Show the total population of those continents with a total population of at least half a billion.

SELECT continent, SUM(population) FROM world
GROUP BY continent
HAVING SUM(population) > 500000000

ENHANCEMENT: List the continents that have a total population of at least 100 million.

SELECT continent FROM world
GROUP BY continent
HAVING SUM(population) >= 100000000  # having的用法

Nobel Laureates-(yr, subject, winner)

Show the year, subject, and name of Physics winners for 1980 together with the Chemistry winners for 1984.

SELECT * FROM nobel
WHERE subject = 'Physics' AND yr = 1980
OR subject = 'Chemistry' AND yr = 1984

Show the year, subject, and name of winners for 1980 excluding Chemistry and Medicine

SELECT * FROM nobel
WHERE subject NOT IN ('Chemistry','Medicine')
AND yr = 1980

Find all details of the prize won by EUGENE O'NEILL
Escaping single quotes: you can't put a single quote in a quote string directly. Instead, use two single quotes within a quoted string.

SELECT * FROM nobel
WHERE winner = 'EUGENE O''NEILL'

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

Show the 1984 winners and subject ordered by subject and winner name; but list Chemistry and Physics last.

SELECT winner, subject, subject IN ('Physics','Chemistry') FROM nobel
WHERE yr=1984
ORDER BY subject IN ('Physics','Chemistry') ,subject,winner

SELECT subject IN ('Physics','Chemistry')可以返回一列(T=1,F=0);升序排列


Show the amount of years where no Medicine awards were given

SELECT COUNT(DISTINCT yr) FROM nobel
WHERE yr NOT IN (SELECT DISTINCT yr FROM nobel WHERE subject = 'Medicine')
# 以下为错误写法
SELECT COUNT(DISTINCT yr) FROM nobel
WHERE yr IN (SELECT DISTINCT yr FROM nobel WHERE subject <> 'Medicine')

Show the year when neither a Physics or Chemistry award was given

SELECT yr FROM nobel
WHERE yr NOT IN (SELECT yr FROM nobel
                 WHERE subject IN ('Chemistry','Physics'))

Show the years when a Medicine award was given but no Peace or Literature award was given

SELECT DISTINCT yr FROM nobel
WHERE subject= 'Medicine' 
   AND yr NOT IN(SELECT yr FROM nobel 
                 WHERE subject='Literature')
   AND yr NOT IN (SELECT yr FROM nobel
                  WHERE subject='Peace')

CASE...WHEN...THEN...

CASE allows you to return different values under different conditions.

CASE WHEN condition1 THEN value1 
     WHEN condition2 THEN value2  
     ELSE def_value 
END 

例:

SELECT name, population
      ,CASE WHEN population<1000000 
            THEN 'small'
            WHEN population<10000000 
            THEN 'medium'
            ELSE 'large'
       END
  FROM bbc
name population CASE WHEN pop..
Afghanistan 26000000 large
Albania 3200000 medium
Algeria 32900000 large
... ... ...

你可能感兴趣的:(SQLZOO笔记(一))