case when then else_(五)SQL知识点--UNION、各类JOIN、CASE

47b8960fc5d75eb7ce8da20ffa72b4d3.png

6f782e4e35267decdf2844b4e4710c0c.png

1. 组合查询 UNION

UNION 联合,将多条查询语句的结果合并成一个结果,可以理解为是将多表结果加在一起。

  • 语法:
查询语句1
UNION/UNION ALL
查询语句2
...
  • 应用场景:

要查询的结果来自于多个表,且多个表没有直接的连接关系,但查询的信息一致时。

  • 特点:
  1. 要求多条查询语句的查询列数保持一致;
  2. 要求多条查询语句查询的每一列的类型和顺序最好一致(不一致也不会报错,但内容就乱了);
  3. union 关键字默认去重,如果使用union all可以包含重复项。

c0437a7c240e604087080b4e15691e29.png

2. 多表联结 JOIN

联结是指,将多个存在相关关系的数据表,通过指定的条件(字段之间的比较运算),联结成一个数据表的过程。

【分类】

  • CROSS JOIN --交叉联结
  • INNER JOIN --内联结
  • LEFT JOIN --左联结
  • RIGHT JOIN --右联结
  • FULL JOIN --全联结

a8a287adaaa1cf442dd1d8bd4e487602.png

注意:多表联结,每个表名建议起别名。

2.1 交叉联结 CROSS JOIN

又称笛卡尔积,是将每个表的所有行都联结在一起,联结表的行数=表1的行数 * 表2的行数。

为了便于理解,我列出2个简单数据表来表示联结关系。

407d7e482c11c2474c34550287dc062f.png

2.2 内联结 INNER JOIN

内联结就是等值联结,只保留多个表里的交集数据。

00399c277175261006db4ab8be1aa625.png

案例:

ae4a87deba0a89c6636b32963ebb285d.png

2.3 左联结 LEFT JOIN

左联结是在多个表数据联结时保留下左边表的所有数据,和右边表满足关系条件的数据。

  • 常见关系条件是相等关系(=)

927c2de65c7435912244a866b2d5893a.png
  • 关系条件也可以是不等值关系(<,>,<=,>=,<>)

38db7c4ee4793410af8e9bbeec3de612.png
  • 只取左表仅有的数据

f17dde64062bb90802d553cd1a85bd9d.png

案例:

772bff1cccf672243abaa27ac8bb0ea6.png

当多表联结的联结类型变化了一个,结果也不同:

535b9c350c427fe3cf4f7dc0ca7db669.png

2.4 右联结 RIGHT JOIN

右联结是在多个表数据联结时保留下右边表的所有数据,和左边表满足关系条件的数据。

106240f48895f62e16d7598934bdbcad.png

案例:

51bfaa91aa11ba162f9378441c2f9290.png

2.5 全联结 FULL JOIN

全联结查询结果是保留多个表里的所有行,满足联结关系条件的数据行合并只保留一次,待联结的表在其他表里匹配不到满足关系条件的数据时其他表里用null填充。

2945f6cf9931f7b42e7d70e5abfcfebc.png

(but,Mysql不支持全联结~~~)

3. JOIN语句练习

d2e7ce4078e231171a36e11a2fd094dd.png

6c24275f1a79ec439c0de40b63dcce9a.png

4866967594db7446bd5c7f8219b1c39e.png

4. 判断函数--CASE

应用场景:自定义分组、统计有筛选条件的数量等

  • 语法一:
CASE 变量或要判断的字段或表达式
WHEN 常量1 THEN 要显示的值1(或语句1;)
WHEN 常量2 THEN 要显示的值2(或语句2;)
....
ELSE 要显示的值n(或语句n;)
END

当case语句放在select语句中作为表达式来使用时,此时case结构中就不能含有语句部分。

  • 语法二:
CASE WHEN 条件1 THEN 要显示的值1(或语句1;)
     WHEN 条件1 THEN 要显示的值2(或语句2;)
     ....
     ELSE 要显示的值n(或语句n;)
     END
  • 语法一和语法二的区别在case后是否有内容,语法一是等值判断,when后省略等于号;语法二是区间判断。
  • ELSE 可以省略,对应的结果会自动填充为NULL。

案例:

9fe8b7732f9d9b3e3d06aca929e261df.png

52502a82da20538cff287f61e6c06250.png

d24efb188e5771a972f01f9446ce9585.png

5. sqlzoo练习

表信息如下:

赛事表game: 
         id(编号),mdate(日期),stadium(场馆),team1(队伍1编号),team2(队伍2编号)
入球表goal:
          matchid(赛事编号),teamid(队伍编号),player(入球球员),gtime(入球时间)
欧洲队伍表eteam:
         id(编号),teamname(队名),coach(教练)

0c236f0311cac2eb83129101ac7ab36e.png

题目如下:

#1.列出 賽事編號matchid 和球員名 player ,該球員代表德國隊Germany入球的。
SELECT matchid,player
FROM goal
WHERE teamid='GER';


#2.由以上查詢,你可見Lars Bender's 於賽事 1012入球。.現在我們想知道此賽事的對賽隊伍是哪一隊。只顯示賽事1012的 id, stadium, team1, team2
SELECT id,stadium,team1,team2
FROM game
WHERE id='1012';


#3.顯示每一個德國入球的球員名,隊伍名,場館和日期。
SELECT player,teamid,stadium,mdate
FROM goal AS a 
     INNER JOIN game AS b ON a.matchid=b.id
WHERE a.teamid='GER;


#4.列出球員名字叫Mario (player LIKE 'Mario%')有入球的 隊伍1 team1, 隊伍2 team2 和 球員名 player。
SELECT team1,team2,player
FROM game AS a
     INNER JOIN goal AS b ON a.id=b.matchid
WHERE player LIKE'Mario%';


#5.列出每場球賽中首10分鐘gtime<=10有入球的球員 player, 隊伍teamid, 教練coach, 入球時間gtime
SELECT player,teamid,coach,gtime
FROM goal AS a 
     INNER JOIN eteam AS b ON a.teamid=b.id
WHERE gtime<10;


#6.列出'Fernando Santos'作為隊伍1 team1 的教練的賽事日期,和隊伍名。
SELECT mdate,teamname
FROM eteam AS a
     INNER JOIN game AS b ON a.id=b.team1
WHERE coach='Fernando Santos';


#7.列出場館 'National Stadium, Warsaw'的入球球員。(!注意名字Warsaw前和逗号之前有空格)
SELECT b.player
FROM game AS a
     INNER JOIN goal AS b ON a.id=b.matchid
WHERE a.stadium ='National Stadium, Warsaw';


#8.列出全部賽事,射入德國龍門的球員名字。
SELECT DISTINCT player
FROM game AS a 
     INNER JOIN goal AS b ON a.id=b.matchid
WHERE (team1='GER'
   OR team2='GER')
AND teamid!='GER';


#9.列出隊e伍名稱 teamname 和該隊入球總數
SELECT teamname,COUNT(player)
FROM eteam AS a 
     INNER JOIN goal AS b ON a.id=b.teamid
GROUP BY teamname;


#10.列出場館名和在該場館的入球數字。
SELECT stadium,COUNT(player)
FROM game AS a 
     INNER JOIN goal AS b ON a.id=b.matchid
GROUP BY stadium;


#11.每一場波蘭'POL'有參與的賽事中,列出賽事編號 matchid, 日期date 和入球數字。
SELECT matchid,mdate,COUNT(teamid)
FROM game AS a
     INNER JOIN goal AS b ON a.id=b.matchid
WHERE team1='POL' 
   OR team2='POL'
GROUP BY matchid,mdate;


#12.每一場德國'GER'有參與的賽事中,列出賽事編號 matchid, 日期date 和德國的入球數字。
SELECT matchid,mdate,COUNT(teamid)
FROM game AS a
     INNER JOIN goal AS b ON a.id=b.matchid
WHERE (team1='GER' 
        OR team2='GER')
  AND teamid='GER'
GROUP BY matchid,mdate;


#13. 查出所有比赛日期,每场比赛双方各自的进球数。
SELECT a.mdate,
       a.team1,
       SUM(CASE WHEN b.teamid=a.team1 THEN 1 ELSE 0 END)AS score1,
       a.team2,
       SUM(CASE WHEN b.teamid=a.team2 THEN 1 ELSE 0 END)AS score2
FROM game AS a
     LEFT JOIN goal AS b
       ON a.id=b.matchid
GROUP BY a.mdate,a.team1,a.team2
ORDER BY a.mdate,a.id,a.tea
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值