in多个条件不走索引 inner join on 多条件_mysql


一、大纲


in多个条件不走索引 inner join on 多条件_in多个条件不走索引_02


in多个条件不走索引 inner join on 多条件_sql_03


二、实战

1.表的加法-union

提前准备好结构相同的course表和course1表


in多个条件不走索引 inner join on 多条件_mysql_04

course表

in多个条件不走索引 inner join on 多条件_in多个条件不走索引_05

course1

(1)将两个course和course1表的内容合并,不保留重复值


select


in多个条件不走索引 inner join on 多条件_sql_06

运行结果1-去重union

(2)将两个course和course1表的内容合并,保留重复值


select *
from course
union all
select *
from course1;


in多个条件不走索引 inner join on 多条件_.net_07

运行结果2-union all不去重

2.表的联结-交叉联结cross join+内联结inner join+左连接left join+右联结right join+全联结full join

student表


in多个条件不走索引 inner join on 多条件_sql_08


score表


in多个条件不走索引 inner join on 多条件_.net_09


(1)内联结


in多个条件不走索引 inner join on 多条件_sql_10


#内联结inner join
#查询学生的学号,姓名和课程号
select a.学号,a.姓名,b.课程号
from student as a
inner join
score as b
on a.学号=b.学号


in多个条件不走索引 inner join on 多条件_mysql_11

inner join... on ...

(2)左联结


in多个条件不走索引 inner join on 多条件_sql_12


select a.学号,a.姓名,b.课程号
from student as a
left join
score as b
on a.学号=b.学号


in多个条件不走索引 inner join on 多条件_in多个条件不走索引_13


(3)左联结,保留a表中的特有行


in多个条件不走索引 inner join on 多条件_.net_14


select a.学号,a.姓名,b.课程号
from student as a
left join
score as b
on a.学号=b.学号
where b.学号 is null;


in多个条件不走索引 inner join on 多条件_in多个条件不走索引_15


(4)右联结


select a.学号,a.姓名,b.课程号
from student as a
right join
score as b
on a.学号=b.学号


in多个条件不走索引 inner join on 多条件_in多个条件不走索引_16


(5)右联结-删除左表中的空值


select a.学号,a.姓名,b.课程号
from student as a
right join
score as b
on a.学号=b.学号
where a.学号 is null;


in多个条件不走索引 inner join on 多条件_in多个条件不走索引_17


(6)全联结full join

mysql不支持全联结。


in多个条件不走索引 inner join on 多条件_.net_18


in多个条件不走索引 inner join on 多条件_in多个条件不走索引_19


3.联结案例:

(1)#查询所有学生的学号,姓名,学科数目,总成绩

step1:学号,姓名来自student表,直接查询

学科数目和总成绩来自score表,需要左联结

需要对学生进行分组,

之后count(课程号)得到学科数目,sum(成绩)得到总成绩

step2:

select 学号,姓名,选课数,总成绩

from (student表和score表,通过学号左联结,获得课程号计数和成绩求和

where 条件【没有】

group by 学号

having 分组条件【没有】

order by 排序条件【没有】

limit 限制显示条数【没有】

step3:


select a.学号,a.姓名,count(b.课程号) as 选课数,sum(b.成绩) as 总成绩
from student as a
left join
score as b
on a.学号=b.学号
group by 学号;


in多个条件不走索引 inner join on 多条件_mysql_20


(2)查询平均成绩大于85分的所有学生的学号、姓名和平均成绩

step1:学号+姓名【student】

平均成绩【score表】:需要左联结,按照学号分组,avg(成绩)

然后where子句选出平均成绩大于85的学生。

step2:

select a.学号,a.姓名,avg(b.成绩) as 平均成绩

from (表student,score通过学号左联结)

where 条件【没有】

group by 学号

having avg(b.成绩)>85;

order by 排序【没有】

limit 限制显示行数【没有】

step3:


select a.学号,a.姓名,avg(b.成绩) as 平均成绩
from student as a
left join score as b
on a.学号=b.学号
group by a.学号
having avg(b.成绩)>85;


in多个条件不走索引 inner join on 多条件_mysql_21


(3)查询学生的选课情况:显示学号,姓名,课程号,课程名称

step1:学号,姓名【student】

课程号,课程名称【course】

step2:select 学号,姓名,课程号,课程名称

from 表【student和score通过学号左联结,score和course表通过课程号内联结】

where 条件【没有】

group by 分组条件【没有】

having 分组条件【没有】

order by 排序条件【没有】

limit 限制显示条数【没有】

step3:


select a.学号,a.姓名,c.课程号,c.课程名称
from student as a left join score as b on a.学号=b.学号
inner join course as c on b.课程号=c.课程号;


in多个条件不走索引 inner join on 多条件_sql_22


4.case表达式


in多个条件不走索引 inner join on 多条件_.net_23


(1)查询学生的成绩是及格还是不及格


in多个条件不走索引 inner join on 多条件_mysql_24


(2)查询出每门课程的及格人数和不及格人数

step2:在score表利用课程号对课程进行分组,对成绩进行评定,及格(>=60),不及格(<60),然后统计人数。

step3:

select 课程号,及格人数,不及格人数

from score

group by 课程号

及格人数:

sum(case when 成绩>=60 then 1

else 0

end) as 及格人数

不及格人数:

sum(case when 成绩<60 then 1

else 0

end) as 不及格人数


select 课程号,
sum(case when 成绩>=60 then 1
         else 0
    end) as 及格人数,
sum(case when 成绩<60 then 1
       else 0
      end) as 不及格人数
from score
group by 课程号;


in多个条件不走索引 inner join on 多条件_in多个条件不走索引_25


(3)使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,分别统计

各分数段人数、课程号和课程名称

step1:课程号,课程名称【course】

分数段【score表和course表右联结,使用sum统计人数,case来分段】

step3:


select a.课程号,b.课程名称,
sum( case when 成绩 between 100 and 85 then 1 else 0
          end) as '[100-85]',
sum( case when 成绩 between 70 and 85 then 1 else 0
          end) as '[85-70]',
sum( case when 成绩 between 60 and 70 then 1 else 0
          end) as '[70-60]',
sum( case when 成绩 <60 then 1 else 0
          end) as '[<60]'
from score as a right join course as b on a.课程号=b.课程号
group by a.课程号,b.课程名称;


in多个条件不走索引 inner join on 多条件_.net_26


拓展练习:

https://sqlzoo.net/wiki/The_JOIN_operation/zhsqlzoo.net


练习结果如下:


in多个条件不走索引 inner join on 多条件_.net_27


SELECT matchid,player FROM goal 
  WHERE teamid = 'GER'


in多个条件不走索引 inner join on 多条件_sql_28


SELECT id,stadium,team1,team2
  FROM game 
where id=1012


in多个条件不走索引 inner join on 多条件_sql_29


SELECT goal.player,goal.teamid,game.stadium,game.mdate
  FROM game JOIN goal ON (game.id=goal.matchid)
WHERE teamid = 'GER'


in多个条件不走索引 inner join on 多条件_sql_30


SELECT a.team1,a.team2,b.player
  FROM game as a JOIN goal as b ON (a.id=b.matchid)
WHERE b.player LIKE 'Mario%'


in多个条件不走索引 inner join on 多条件_sql_31


SELECT b.player,b.teamid,c.coach,b.gtime
  FROM goal as b inner JOIN eteam as c on b.teamid=c.id
 WHERE b.gtime<=10;


in多个条件不走索引 inner join on 多条件_mysql_32


select a.mdate,c.teamname
from game as a JOIN eteam as c ON (a.team1=c.id)
where c.coach='Fernando Santos' ;


in多个条件不走索引 inner join on 多条件_sql_33


select b.player
from game as a inner JOIN goal as b on a.id=b.matchid
where a.stadium='National Stadium, Warsaw'


in多个条件不走索引 inner join on 多条件_sql_34


SELECT distinct b.player
  FROM game as a JOIN goal as b ON b.matchid = a.id 
    WHERE (b.teamid=a.team1 and a.team2='GER'
or b.teamid=a.team2 and a.team1='GER')


in多个条件不走索引 inner join on 多条件_mysql_35


SELECT c.teamname, count(b.teamid)
  FROM eteam as c right JOIN goal as b ON c.id=b.teamid
 group by b.teamid
 ORDER BY teamname


in多个条件不走索引 inner join on 多条件_sql_36


select a.stadium,count(a.id)
from  game as a JOIN goal as b ON b.matchid = a.id 
group by a.stadium


in多个条件不走索引 inner join on 多条件_in多个条件不走索引_37


SELECT b.matchid,a.mdate,count(a.id)
  from  game as a inner JOIN goal as b ON b.matchid = a.id 
 WHERE (a.team1 = 'POL' OR a.team2 = 'POL')
group by a.id


in多个条件不走索引 inner join on 多条件_mysql_38


SELECT b.matchid,a.mdate,count(a.id)
  from  game as a inner JOIN goal as b ON b.matchid = a.id 
 WHERE b.teamid='GER'
group by a.id


in多个条件不走索引 inner join on 多条件_.net_39


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 b.matchid = a.id
group by a.mdate, b.matchid, a.team1,a.team2;