数据库 多表连接查询

– 多表查询,也叫多表连接查询。
/*
按连接的情况不同可以分为:
等值连接 非等值连接
等值连接:通过条件是否相等做连接查询
非等值连接:不是通过条件是否相等做连接查询
内连接 外连接
内连接 inner JOIN (inner可以省略)
外连接 out join (outer可以省略)
left join—左外连接
right join—右外连接
full join----全连接(mysql不支持)
自连接 非自连接
同一张表相互连接叫自连接。
不同的表之间连接叫非自连接。
*/
– 笛卡尔积 :表1和表2中所有的数据都可以结合,而且认为结合后是对的。
用到的表:
student(sid,sname,sage,ssex,leaderid) 学生表 sid:学号;sname:学生姓名;sage:学生年龄;ssex:学生性别 leaderid:组长id
course(cid,cname,tid) 课程表 cid,课程编号;cname:课程名字;tid:教师编号
score(cid,sid,sscore) 成绩表 sid:学号;cid,课程编号;sscore:成绩
teacher(tid,tname,cid) 教师表 tid:教师编号; tname:教师名字 cid:课程名
scorelevel(level,minScore,maxScore) level:等级 minScore:最低成绩 maxScore:最高成绩
!表中内容没有给出

– 查询老师的姓名以及老师教的课程名称。
– 给表或者给查询的字段起别名,使用as关键字(as可以省略)。别名写在原始表的后面(要空格)
select t.tid as “老师编号”,t.tname “老师姓名”,t.cid “课程 编号”,cname “课程名称”
from teacher t,course c
where t.cid = c.cid;

– 查询 学习1001课程的学生信息
select s.*
from student s, score s2
where s.sid = s2.sid
and s2.cid = 1001;

– 查询 学习1001课程的学生姓名,学号,年龄,性别,课程名,成绩
select s.,c.,s2.*
from student s,course c,score s2
where s.sid = s2.sid
and c.cid = s2.cid
and c.cid = 1001;

– sql92的连接查询语法。—1992年协会定义的sql语法。
/*
select 放的是你要查询的所有的字段(可以是不同表的字段)
from 放的是字段所属的表
where 放的是所有的过滤条件。
sql92的优势:select以及from很好写。where条件很难写,条件很复杂。
*/

– sql99定义了另外一种多表连接的语法。截至到今天用的最为广泛。
– select 字段列表 from 表1 join 表2 on 条件 join 表3 on 条件。。。

– 查询 学习1001课程的学生姓名,学号,年龄,性别,课程名,成绩
select sname,s.sid,sage,ssex,cname,sscore
from student s
join score s2
on s.sid = s2.sid
join course c
on c.cid = s2.cid and c.cid = 1001;

– 查询成绩表中每条信息以及成绩对应的级别。
select s.*,sl.level
from score s, scoreLevel sl
where s.sscore between sl.minScore and sl.maxScore;

select s.*,sl.level
from score s
join scoreLevel sl
on s.sscore between sl.minScore and sl.maxScore;

– 外连接:不仅把满足条件的查出来,把不满条件的也查出来。
– 左外连接:不仅把满足条件的查出来,还把左表中不满足条件的查出来
– 右外连接:不仅把满足条件的查出来,还把右表中不满足条件的查出来

– 查询所有学生的成绩和学生信息。
select s.,s2.
from student s left join score s2
on s.sid = s2.sid;

select concat(s2.sname , ‘是’ ,s1.sname ,‘的组长’) as 描述
from student s1,student s2
where s1.leaderid = s2.sid;

– 1、查询 孔丘 教授的课程编号和课程名称
select t.tname,c.cid,c.cname
from teacher t, course c
where t.cid = c.cid
and tname = ‘孔丘’;

select t.tname,c.cid,c.cname
from teacher t join course c
on t.cid = c.cid and t.tname = ‘孔丘’;

#2、查询 哪些学生 学习了孔丘的课,课程名称是什么?
select c.cname,s1.sname
from teacher t, course c, score s2, student s1
where t.tid = c.tid and t.tname = ‘孔丘’
and c.cid = s2.cid and s1.sid = s2.sid;

select c.cname,s1.sname
from course c join teacher t
on t.tid = c.tid and t.tname = ‘孔丘’
join score s2
on s2.cid = c.cid
join student s1
on s1.sid = s2.sid;

#3、查询 哪些学生 学习了孔丘的课,课程名称是什么,考了多少分?
select s.sname, c.cname, s1.sscore
from student s join score s1
on s.sid = s1.sid
join course c
on s1.cid = c.cid
join teacher t
on t.tid = c.tid and t.tname = ‘孔丘’;

select s.sname, c.cname, s1.sscore
from teacher t,course c,student s,score s1
where t.tid = c.tid and s.sid = s1.sid and c.cid = s1.cid
and t.tname = ‘孔丘’;

#4、查询 哪些学生 学习了孔丘的课,课程名称是什么,考了多少分,
#属于什么等级?
select s.sname, c.cname,ss.sscore,level
from student s,course c,score ss,teacher t,scoreLevel
where s.sid = ss.sid and ss.cid = c.cid and c.tid = t.tid
and t.tname = ‘孔丘’ and ss.sscore between scoreLevel.minScore
and scoreLevel.maxScore;

select s.sname, c.cname,ss.sscore,level
from student s join score ss
on s.sid = ss.sid
join course c
on ss.cid = c.cid
join teacher t
on t.tid = c.tid and t.tname = ‘孔丘’
join scoreLevel sl
on ss.sscore BETWEEN sl.minScore and sl.maxScore;

#时间函数
select now();-- 获取当前时间 yyyy-MM-dd HH:mm:ss

#字符串函数
/*lower(string)----字符串小写
upper(string)----字符串大写
concat(string,string,…)----字符串连接
substr(string,index,count)----求字串,index从1开始。
length(string)----求字符串长度
instr(string,substring)----查找字符串位置。没有返回0
lpad(str,len,padstr)----左补齐
rpad(str,len,padstr)----右补齐
trim(str)----去除左右两侧的空白
replace(orignStr,replace,target)----字符串替换
*/

select lower(‘Hello WORld’) lower, upper(‘hello world’) upper;

select concat(‘四火哥’,‘喜欢’,‘与’,‘娄女士’,‘搞飞机’) lianjie;

select SUBSTR(‘hello world’,1,5) subStr;

select length(“hello world”) length;

select instr(‘hello world’,‘z’) instr;-- 如果不包含,返回0,包含的话,返回下标

select lpad(‘hello’,10,’-=+’);-- left padding

select rpad(‘hello’,10,’!’);-- right padding

select trim(’ hello world ');

select REPLACE(“hello world”,‘lo’,’*’);

/*
round(num,dotnum)----四舍五入
truncate(num,dotnum)----截断
mod(num,num2)----求余
*/

select round(123.456,2);
select round(123.456,1);
select round(123.456,0);
select round(123.456,-2);

select truncate(123.456,2);
select truncate(123.456,1);
select truncate(123.456,-2);

select MOD(11,3);

select *, case sname when ‘周星驰’ then ‘周星星’
when ‘成龙’ then ‘房祖名他爹’
when ‘刘德华’ then ‘朱丽倩的老公’
else ‘不关心’
end 备注
from student
where sage > 40;

select * , case
when (sage >= 60 and ssex = ‘男’) or (sage >= 55 and ssex = ‘女’)
then ‘老年’
when sage between 40 and 59 then ‘中年’
when sage between 30 and 39 then ‘壮年’
when sage between 18 and 29 then ‘青年’
else ‘少年’
end 年龄段
from student;

上面的函数称为 单行函数。

分组函数(多行函数)

/*
max()
min()
avg()
sum()
count()
*/

select max(sage) maxAge , min(sage) minAge,sum(sage) sumAge,
avg(sage) avgAge,count(sage),count(*)
from student;

/*
分组查询是重点!
面试必问。
group by 列名
分组自动去重。
select 筛选的字段(分组函数除外)一定要出现在group by后面,否则没有意义。

一般group by 与分组函数连用
或者group by 与having连用

*/
select ssex,count(ssex) as count
from student
group by ssex;

分完组以后,只能用having去过滤数据,不能用where过滤数据。

select sage
from student
group by sage
having sage > 30 and sage < 50;

– 查询大于平均年龄的学生的信息
select *
from student
where sage > (
select avg(sage)
from student
)

猜你喜欢

转载自blog.csdn.net/weixin_43791238/article/details/90106070