SqlZoo错题整理2

接上篇:SqlZoo错题整理

1、The_JOIN_operation

网址:https://sqlzoo.net/wiki/The_JOIN_operation
涉及到的表及其关系说明如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
8、The example query shows all goals scored in the Germany-Greece quarterfinal.Instead show the name of all players who scored a goal against Germany.
HINT(提示):Select goals scored only by non-German players in matches where GER was the id of either team1 or team2.
You can use teamid!=‘GER’ to prevent listing German players.
You can use DISTINCT to stop players being listed twice.

这道题目本身不难,就是英语不太过关,看了半天题目才看懂…
Instead show the name of all players who scored a goal against Germany.
翻译:而是显示所有在对德国队比赛中进球的球员的名字。

SELECT distinct(player)
	FROM game 
		JOIN goal ON matchid = id 
	WHERE (team1='GER' or team2='GER') AND teamid!='GER'

13、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.
在这里插入图片描述
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.
case when…then…的用法介绍

# 原来CASE WHEN...THEN和SUM组合使用的语法是这样,学到了
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

2、More_JOIN_operations

网址:https://sqlzoo.net/wiki/More_JOIN_operations.
对需要用到的表的介绍:https://sqlzoo.net/wiki/More_details_about_the_database.

6.Obtain the cast list for ‘Casablanca’.
what is a cast list?The cast list is the names of the actors who were in the movie.
Use movieid=11768, (or whatever value you got from the previous question)

# 可以使用嵌套查询
SELECT a.name 
	FROM actor a 
		JOIN casting c ON a.id=c.actorid 
	WHERE c.movieid=(SELECT id 
					 	FROM movie 
				 	 WHERE title='Casablanca')

7.Obtain the cast list for the film ‘Alien’.

# 原理与上面一题一样,这里可以用另一种方式:因为涉及到三张表,可以三表join
SELECT a.name 
	FROM actor a JOIN casting c ON a.id=c.actorid 
                 JOIN movie m ON m.id=c.movieid 
WHERE m.title='Alien'

12.List the film title and the leading actor for all of the films ‘Julie Andrews’ played in.
错误做法:

SELECT m.title,a.name 
	FROM casting c JOIN movie m ON m.id=c.movieid
                   JOIN actor a ON a.id=c.actorid
	WHERE a.name='Julie Andrews'

以上做法筛选出来的只是Julie Andrews参演的所有电影,并不能找到对应的leading actor。
正确做法:

# 通过where条件从casting表中找出Julie Andrews参演的所有电影的movieid(即c.movieid),
# 再在表连接中限制c.ord=1,查询出m.title和a.name
SELECT m.title,a.name 
	FROM casting c 
		JOIN movie m ON m.id=c.movieid AND c.ord=1
    	JOIN actor a ON a.id=c.actorid
	WHERE c.movieid IN (SELECT movieid FROM casting 
							JOIN actor ON id=actorid 
					    	WHERE name='Julie Andrews')

13.Obtain a list, in alphabetical order, of actors who’ve had at least 15 starring roles.

扫描二维码关注公众号,回复: 14861575 查看本文章
SELECT a.name 
	FROM actor a JOIN casting c ON a.id=c.actorid 
	WHERE c.ord=1 GROUP BY a.name HAVING COUNT(*)>=15 

14.List the films released in the year 1978 ordered by the number of actors in the cast, then by title.
注意: order by后面也可以跟聚合函数。

SELECT m.title,COUNT(c.actorid) 
	FROM movie m JOIN casting c ON m.id=c.movieid 
	WHERE m.yr=1978 
		GROUP BY m.title 
		ORDER BY COUNT(c.actorid) DESC,m.title

15.List all the people who have worked with ‘Art Garfunkel’.

# 注意:最后要加AND a.name!='Art Garfunkel'
SELECT a.name 
	FROM casting c JOIN actor a ON c.actorid=a.id 
                   JOIN movie m ON c.movieid=m.id
	WHERE c.movieid IN 
	(SELECT movieid 
		FROM casting 
			JOIN actor ON actorid=id 
		WHERE name='Art Garfunkel') 
	AND a.name!='Art Garfunkel'

3、COALESCE 和 IFNULL

网址:https://sqlzoo.net/wiki/COALESCE
COALESCE是一个函数,返回传入的参数中第一个非NULL的值,可以接受两个或两个以上参数(上限个数目前还不清楚)。
如:

SELECT COALESCE(NULL,1); -->1
SELECT COALESCE(NULL, NULL, 1);  --> 1 
SELECT COALESCE(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1); --> 1 

如果传入的参数所有都是null,则返回null,比如

SELECT COALESCE(NULL, NULL, NULL, NULL); --> NULL 

**这个函数使用的场合为:假如某个字段默认是null,你想其返回的不是null,而是比如0或其他值,可以使用这个函数: **

SELECT COALESCE(field_name,0) as value from table;

类似函数:
IFNULL(x,y):如果x为NULL,则返回后面设置的y,否则返回x,一般使用场合同上(只能用于mysql数据库中);
HINT(提示):

1)在所有数据库中只要有NULL参与的数学运算,最终结果就是NULL,为避免这个现象,需要使用IFNULL()或者COALESCE()函数;
2)在数据库中,NULL就是空,啥值都没有,而不是显示为NULL。

4、NULLIF和NVL

1. NULLIF(x,y):如果x等于y,则返回NULL,否则返回x;
2.NVL(x,y) :与IFNULL()函数用法一致,只是其只能用于orcale数据库中

以上各个函数在不同数据库中的支持情况总结:

函数名 Oracle Mysql SqlServer
COALESCE(x,y,z)
IFNULL(x,y,z)
NVL(x,y,z)
NULLIF(x,y)

在这里再附上SQL的函数一览表:https://sqlzoo.net/wiki/FUNCTIONS

5、Self_join

网址:https://sqlzoo.net/wiki/Self_join

所需要用到的表:

stops(id, name)
route(num, company, pos, stop)

字段详细描述:https://sqlzoo.net/wiki/Edinburgh_Buses

3.Give the id and the name for the stops on the ‘4’ ‘LRT’ service.

# 这里需要注意的是在route表中num的类型为char型,
# 所以要用r.num='4',而不是r.num=4
SELECT s.id,s.name 
	FROM stops s 
		JOIN route r ON s.id=r.stop 
	WHERE r.company='LRT' AND r.num='4'  

7.Give a list of all the services which connect stops 115 and 137 (‘Haymarket’ and ‘Leith’)

SELECT a.company, a.num
	FROM route a JOIN route b ON
		(a.company=b.company AND a.num=b.num)
	WHERE a.stop='115' and b.stop='137' 

以上筛选会有多条一样的数据,虽然显示的数据a.company和a.num一样,但是实际上a.pos和b.pos不一样,这是因为一条路线上可能会多次访问同一个站点,所以a.company和a.num一样,而实际在该路线的停止顺序(即a.pos和b.pos)不一样,所以需要去重。
去重方法:
法1.通过使用GROUP BY a.company,a.num达到分组后自动去重的目的

SELECT a.company, a.num
	FROM route a 
		JOIN route b ON (a.company=b.company AND a.num=b.num)
	WHERE a.stop=115 and b.stop=137 
		GROUP BY a.company,a.num

法2.使用distinct关键字
错误写法:

SELECT a.company,distinct a.num
	FROM route a 
		JOIN route b ON (a.company=b.company AND a.num=b.num)
	WHERE a.stop=115 and b.stop=137 

正确写法:

SELECT distinct a.company,a.num
	FROM route a 
		JOIN route b ON (a.company=b.company AND a.num=b.num)
	WHERE a.stop=115 and b.stop=137 

注意:distinct只能出现在所有字段的最前方表示对后面所有字段进行联合去除重复记录

9.Give a distinct list of the stops which may be reached from ‘Craiglockhart’ by taking one bus, including ‘Craiglockhart’ itself, offered by the LRT company. Include the company and bus no. of the relevant services.

SELECT st.name,a.company,a.num 
	FROM route a JOIN route b ON a.company=b.company AND a.num=b.num 
				 JOIN stops s ON s.id=a.stop
				 JOIN stops st ON st.id=b.stop 
	WHERE s.name='Craiglockhart' AND a.company='LRT'

10.Find the routes involving two buses that can go from Craiglockhart to Lochend.
Show the bus no. and company for the first bus, the name of the stop for the transfer,
and the bus no. and company for the second bus.
哇,感觉最一题的难度突然就提起来了。想了一会,没有十分明确的思路就在CSDN上查了一下,发现了https://blog.csdn.net/weixin_42012759/article/details/112873521
上面这篇博文里有十分详细的解释,看了前面一半的讲解加上后面有博主的评论就有了思路。
题目解析:

题目的意思是求解Craiglockhart——>Lochend的含有中转站的大巴路线,查询后显示起始站的num,起始站的company,中转站的name,终点站的num,终点站的company。

步骤:

1、查询出起始站为name=Craiglockhart的所有车,将数据存入虚拟表a;
2、查询出终点站为name=Lochend站的所有车,将数据存入虚拟表b;
3、进行两表连接,连接条件为a表的终点站等于b表的起始站(即作为中转站)。

SELECT a.num firstNum, a.company firstCom, a.name transfer , b.num secondNum, b.company secondCom
  FROM(SELECT r1.num, r1.company, s2.name
         FROM route r1 JOIN route r2 ON r1.company = r2.company 
          AND r1.num = r2.num
         JOIN stops s1 ON r1.stop = s1.id
         JOIN stops s2 ON r2.stop = s2.id
        WHERE s1.name = 'Craiglockhart') a 
  JOIN(SELECT r2.num, r2.company, s1.name
         FROM route r1 JOIN route r2 ON r1.company = r2.company 
          AND r1.num = r2.num
         JOIN stops s1 ON r1.stop = s1.id
         JOIN stops s2 ON r2.stop = s2.id
        WHERE s2.name = 'Lochend') b 
    ON a.name = b.name
    GROUP BY firstNum, firstCom, transfer, secondNum, secondCom

注意:查询完后需要使用GROUP BY分组才能得到Correct answer!

6、结语

到此为止Sqlzoo上的题目就全部刷完啦(完结撒花~( ̄▽ ̄)~ )!感觉这么做下来感觉Sqlzoo既是一个练题的网站,也是一个对SQL的基础学习的网站,里面每个语句、函数都有很详尽的解释(虽然全英文式有的时候读得有点头大,也算是对英文阅读的一种锻炼了!( ̄ェ ̄;)。目前练到的只是SQL的基础,还要再接再厉!

猜你喜欢

转载自blog.csdn.net/weixin_45041745/article/details/120190523
今日推荐