1. 程式人生 > >SQL入門筆記2——子查詢,JOIN,GROUP BY

SQL入門筆記2——子查詢,JOIN,GROUP BY

                           一、SELECT 子查詢

例1.SQLZOO:SELECT within SELECT
T7、在每一個州中找出最大面積的國家,列出洲份 continent, 國家名字 name 及面積 area。 (有些國家的記錄中,AREA是NULL,沒有填入資料的。)

SELECT continent,name,area
FROM world x
WHERE x.area >=ALL
    (SELECT area FROM world y
    WHERE x.continent=y.continent AND area>0
)

在子查詢句子中,如果需要將表中的資料自己與自己對比,就需要將表的名字加一個別名,如上例中的x,y

例1.SQLZOO:SELECT within SELECT
T8.列出洲份名稱,和每個洲份中國家名字按子母順序是排首位的國家名。(即每洲只有列一國)

SELECT continent,name
FROM world x
WHERE x.name=(SELECT name FROM world y
    WHERE x.continent=y.continent
    ORDER BY name LIMIT 1)
/*LIMIT 用在SELECT中,強制返回指定的記錄數。LIMIT n(LIMIT 0
,n)返回前n條記錄*/
               二、JOIN和GROUP BY

例一:SQLZOO:The JOIN operation
T9:列出隊伍名稱 teamname 和該隊入球總數
COUNT and GROUP BY

SELECT teamname,COUNT(teamid)
FROM eteam JOIN goal ON eteam.id=goal.teamid
GROUP BY goal.teamid

提示:gisq:eteam.teamname isn’t in group by

SELECT teamname,COUNT(teamid)
FORM eteam JOIN
goal ON eteam.id=goal.teamid GROUP BY eteam.teamname

該答案正確,猜想:是否group by 後面一定要跟SELECT後的列名

例二:T13:List every match with the goals scored by each team as shown. This will use “CASE WHEN” which has not been explained in any previous exercises.
mdate team1 score1 team2 score2
1 July 2012 ESP 4 ITA 0
10 June 2012 ESP 1 ITA 1
10 June 2012 IRL 1 CRO 3

Notice in the query given every goal is listed. If it was a team1 goal then a 1 appears in score1, otherwise there is a 0. You could SUM this column to get a count of the goals scored by team1. Sort your result by mdate, matchid, team1 and team2.

SELECT mdate,team1,SUM(
CASE WHEN game.team1=goal.teamid THEN 1 ELSE 0 END) AS score1,
team2,SUM(
CASE WHEN game.team2=goal.teamid THEN 1 ELSE 0 END)AS score2
From game LEFT JOIN goal ON game.id=goal.matchid
GROUP BY mdate,matchid,team1,team2

注:
1、在上題正確結果中,group by中的引數多於SELECT後的,因而推斷GROUP BY後的必須有SELECT中的,但可以比它多
驗證:將上題中的GROUP BY 後的mdate刪除,果然提示錯誤:’gisq.game.mdate’ isn’t in GROUP BY
2、上題中的JOIN 是使用的 “LEFT JOIN”,因為有可能一場比賽中有可能兩個球隊沒有得分,若是用JOIN 則是至少有一個得分才顯示,可能將都沒有得分的忽略

例三:SQLZOO:More JOIN operation
T12:尊·特拉華達’John Travolta’最忙是哪一年? 顯示年份和該年的電影數目。

SELECT yr,COUNT(title) FROM
  movie JOIN casting ON movie.id=movieid
         JOIN actor   ON actorid=actor.id
where name='John Travolta'
GROUP BY yr
HAVING COUNT(title)=(SELECT MAX(c) FROM
(SELECT yr,COUNT(title) AS c FROM
   movie JOIN casting ON movie.id=movieid
         JOIN actor   ON actorid=actor.id
 where name='John Travolta'
 GROUP BY yr) AS t
)

以上為原文提示答案
個人答案

SELECT yr,COUNT(title)
FROM movie JOIN casting ON movie.id=casting.movieid
JOIN actor ON actor.id=casting.actorid
WHERE actor.name='John Travolta'
GROUP BY yr
OEDER BY COUNT(title) DESC LIMIT 1

以上主要示例三個表如何連線