SQLZOO-Join
小目录:
- 用group by子查询实现having语句的功能
- JOIN ON连接以后,group by 要将select到的两张表内的字段都group by
- LEFT JOIN(左连接)和JOIN(自然连接)的区别
正文:
- 可以使用group by子查询实现having语句的功能,但是没有比较二者速度:
(1) having的方法:
select continent
from world
group by continent
having sum(population) >= 100000000
(2)group by子查询的方法:
select continent
from world x
where 100000000 <= (select sum(population)
from world y
where x.continent = y.continent
)
group by continent
- 做了JOIN ON连接以后,group by 要将select到的两张表内的字段都group by,不然会报错:
(1)以下代码,报错;
error:‘gisq.game.mdate’ isn’t in GROUP BY
原因:没有group by “mdate”字段
SELECT matchid, mdate, count(matchid)
FROM game JOIN goal ON goal.matchid = game.id
WHERE (team1 = 'POL' OR team2 = 'POL')
group by goal.matchid
(2)修正:
(运行正确)
SELECT matchid, mdate, count(matchid)
FROM game JOIN goal ON goal.matchid = game.id
WHERE (team1 = 'POL' OR team2 = 'POL')
group by goal.matchid,mdate
(3)也可以这样:
(运行正确)
这样是可以正常跑的,但是select的字段需求变了,主要是为了验证我之前猜测的 “group by 要将select到的两张表内的字段都group by” 这个要求是否正确。(验证正确)
SELECT matchid, count(matchid)
FROM game JOIN goal ON goal.matchid = game.id
WHERE (team1 = 'POL' OR team2 = 'POL')
group by goal.matchid
- LEFT JOIN(左连接)和JOIN(自然连接)的区别:
LEFT JOIN:会返回所有的行,不论左表有没有匹配右表;
JOIN:只会返回有匹配的行,没有匹配的不返回;
工作中常用LFET JOIN(左连接),因为就算没有匹配这次的任务,也希望返回这些值,不希望工作数据缺失而影响下次任务执行。
(1)以下代码,显示所有的日期的行,包括score1=0 && score2=0(两者不匹配)的行;-- 使用左连接LEFT JOIN
SELECT mdate,
team1,
sum(CASE WHEN goal.teamid=game.team1 THEN 1 ELSE 0 END) as score1,
team2,
sum(CASE WHEN goal.teamid=game.team2 THEN 1 ELSE 0 END) as score2
FROM game LEFT JOIN goal ON goal.matchid = game.id
group by mdate, matchid, team1, team2
(2)以下代码,只显示部分的日期的行,即score1 !=0 or score2 !=0(两者至少有一个匹配)的行;-- 使用自然连接JOIN
SELECT mdate,
team1,
sum(CASE WHEN goal.teamid=game.team1 THEN 1 ELSE 0 END) as score1,
team2,
sum(CASE WHEN goal.teamid=game.team2 THEN 1 ELSE 0 END) as score2
FROM game JOIN goal ON goal.matchid = game.id
group by mdate, matchid, team1, team2