day 05 DQL数据查询语言---连接查询

  由于sql语句不区分大小写,为了书写方便,本文所有命令统一使用小写 

往期内容

目录

一、连接查询

1、内连接

2、外连接

3、三张、四张表.......的连接

二、子查询

1、select 之后

2、from之后

3、where之后


一、连接查询

例如,在t_student表中取班级信息,在t_teacher表中取教师信息,像这样跨多张表的查询方式就是连接查询。

连接查询可以分为内连接、外连接、全连接 


连接查询的关键:

  • 连接的条件,如果不写条件就默认查询笛卡尔乘积 之后的结果!!!! 
  • 起别名,能够清楚的区分不同的表,特别是在自连接的时候!!!
  • 连接次数越多效率越低,避免多表连接 

注!!!!

加条件只是避免笛卡尔乘积现象,只是让他显示我们需要的数据,连接时的匹配次数并没有减少!!!!

#不加任何连接条件的连接查询,查询结果的条数就是两张表条数的乘积

# t_student 和 t_grade 表不加条件连接

mysql> select t_student.stname,t_student.stmath,t_grade.grade from t_student,t_grade;
+--------+--------+--------+
| stname | stmath | grade  |
+--------+--------+--------+
| 赵钱   |     78 | 良好   |

| 孙李   |     74 | 良好   |
| 孙李   |     74 | 优秀   |
| 孙李   |     74 | 不及格 |
+--------+--------+--------+
78 rows in set (0.08 sec)

1、内连接

特点:两张表没有主次关系,是平等的。 


  • 等值连接

即连接条件为等量关系

语法

select  表1.字段名,表2.字段名 ....... from 表1 inner join   表2   on  表1表2的连接条件  where   筛选条件

inner可以省略,加上可以快速看出是内连接。。。。

#查询成绩高于80分的学生的班主任姓名

mysql> select
    -> st.stname,st.stclass,st.stmath,te.tename
    -> from
    -> t_student st
    -> inner join
    -> t_teacher te
    -> on
    -> st.stclass=te.teclass
    -> where st.stmath>80;
+--------+---------+--------+--------+
| stname | stclass | stmath | tename |
+--------+---------+--------+--------+
| 钱七   | 1班     |     93 | 点赞   |
| 左右   | 2班     |     88 | 收藏   |
| 周四   | 2班     |     94 | 收藏   |
| 夏     | 3班     |     82 | 关注   |
| 张三   | 1班     |     87 | 点赞   |
| 甲乙   | 3班     |     88 | 关注   |
| 前后   | 1班     |     93 | 点赞   |
| 周五   | 2班     |     99 | 收藏   |
| 冷烬   | 2班     |    100 | 收藏   |
| 丙丁   | 1班     |     91 | 点赞   |
| 秋     | 3班     |     89 | 关注   |
+--------+---------+--------+--------+
11 rows in set (0.00 sec)

  •  非等值连接

连接条件为非等值关系

语法  同等值连接

#查询3班学生的成绩等级

mysql> select
    -> st.stname,st.stclass,st.stmath,g.grade
    -> from
    -> t_student st
    -> inner join
    -> t_grade g
    -> on
    -> st.stmath<=g.max and st.stmath>=g.min
    -> where
    -> st.stclass='3班';
+--------+---------+--------+--------+
| stname | stclass | stmath | grade  |
+--------+---------+--------+--------+
| 周六   | 3班     |     58 | 不及格 |
| 孙李   | 3班     |     74 | 良好   |
| 秋     | 3班     |     89 | 良好   |
| 周二   | 3班     |     78 | 良好   |
| 甲乙   | 3班     |     88 | 良好   |
| 夏     | 3班     |     82 | 良好   |
| 王五   | 3班     |     68 | 良好   |
+--------+---------+--------+--------+
7 rows in set (0.00 sec)

  • 自连接

自己跟自己进行连接查询

语法  同等值连接

技巧:把一张表看作是两张表

#查询自己学号上一位的学生姓名

mysql> select
    -> st.stno,st.stname,s.stname
    -> from
    -> t_student as st
    -> inner join
    -> t_student as s
    -> on
    -> st.stno=s.stno+1;
+------+--------+--------+
| stno | stname | stname |
+------+--------+--------+
| 5102 | 王五   | 赵钱   |
| 5103 | 上下   | 王五   |

| 5123 | 丙丁   | 周二   |
| 5124 | 周六   | 丙丁   |
| 5125 | 秋     | 周六   |
| 5126 | 孙李   | 秋     |
+------+--------+--------+
25 rows in set (0.00 sec)


#25条记录是因为1号前面没有学生

2、外连接

外连接分为左连接右连接,左连接以join左边的表为主表,右连接以join右边的表为主表!!!


  • 左连接

select  表1.字段名,表2.字段名 ....... from 表1 left  outer join join   表2   on  表1表2的连接条件  where   筛选条件

outer也可以省略,加上可读性更强

#查询3班学生的成绩等级

mysql> select
    -> st.stname,st.stclass,st.stmath,g.grade
    -> from
    -> t_student st
    -> left outer join
    -> t_grade g
    -> on
    -> st.stmath<=g.max and st.stmath>=g.min
    -> where
    -> st.stclass='3班';
+--------+---------+--------+--------+
| stname | stclass | stmath | grade  |
+--------+---------+--------+--------+
| 王五   | 3班     |     68 | 良好   |
| 夏     | 3班     |     82 | 良好   |
| 甲乙   | 3班     |     88 | 良好   |
| 南北   | 3班     |   NULL | NULL   |
| 周二   | 3班     |     78 | 良好   |
| 周六   | 3班     |     58 | 不及格 |
| 秋     | 3班     |     89 | 良好   |
| 孙李   | 3班     |     74 | 良好   |
+--------+---------+--------+--------+
8 rows in set (0.04 sec)

外连接有主次之分,表1为主表是,在表2没有匹配的数据时,也有返回查询结果,只是结果为null。

例如上面的例子,用左连接和内连接的查询结果的条数不一样。

因此,在连接条件相同时,外连接的查询结果的条数一定是大于等于内连接的查询结果的条数!!!!


  • 右连接

select  表1.字段名,表2.字段名 ....... from 表1 right  outer join join   表2   on  表1表2的连接条件  where   筛选条件

outer也可以省略,加上可读性更强

#查询3班学生的成绩等级

mysql> select
    -> st.stname,st.stclass,st.stmath,g.grade
    -> from
    -> t_grade g
    -> right outer join
    -> t_student st
    -> on
    -> st.stmath<=g.max and st.stmath>=g.min
    -> where
    -> st.stclass='3班';
+--------+---------+--------+--------+
| stname | stclass | stmath | grade  |
+--------+---------+--------+--------+
| 王五   | 3班     |     68 | 良好   |
| 夏     | 3班     |     82 | 良好   |
| 甲乙   | 3班     |     88 | 良好   |
| 南北   | 3班     |   NULL | NULL   |
| 周二   | 3班     |     78 | 良好   |
| 周六   | 3班     |     58 | 不及格 |
| 秋     | 3班     |     89 | 良好   |
| 孙李   | 3班     |     74 | 良好   |
+--------+---------+--------+--------+
8 rows in set (0.00 sec)
查询结果跟左连接一样,因此,可以得出: 任何一个右连接都有左连接的写法;任何一个左连接都有右连接的写法。

3、三张、四张表.......的连接

select ...... from  表1    join  表2  on  表1和表2的连接条件  join  表3  on  表1和表3的连接条件 ............

左连接和右连接可以混合使用

#查询1和3班学生的班主任以及成绩等级,缺考按0分处理,并按班级升序,成绩降序排列

mysql> select
    -> st.stname as "姓名",st.stclass as '班级',ifnull(st.stmath,0) as '成绩',
    -> ifnull(g.grade,'缺考') as '成绩等级',
    -> te.tename as '班主任'
    -> from
    -> t_student st
    -> right outer join
    -> t_teacher te
    -> on
    -> st.stclass=te.teclass
    -> left outer join
    -> t_grade g
    -> on
    -> st.stmath between g.min and g.max
    -> where
    -> st.stclass='1班' or st.stclass='3班'
    -> order by
    -> st.stclass ,st.stmath desc;
+------+------+------+----------+--------+
| 姓名 | 班级 | 成绩 | 成绩等级 | 班主任 |
+------+------+------+----------+--------+
| 钱七 | 1班  |   93 | 优秀     | 点赞   |
| 前后 | 1班  |   93 | 优秀     | 点赞   |
| 丙丁 | 1班  |   91 | 优秀     | 点赞   |
| 张三 | 1班  |   87 | 良好     | 点赞   |
| 赵钱 | 1班  |   78 | 良好     | 点赞   |
| 周三 | 1班  |   77 | 良好     | 点赞   |
| 春   | 1班  |   73 | 良好     | 点赞   |
| 冬   | 1班  |   54 | 不及格   | 点赞   |
| 上下 | 1班  |   47 | 不及格   | 点赞   |
| 秋   | 3班  |   89 | 良好     | 关注   |
| 甲乙 | 3班  |   88 | 良好     | 关注   |
| 夏   | 3班  |   82 | 良好     | 关注   |
| 周二 | 3班  |   78 | 良好     | 关注   |
| 孙李 | 3班  |   74 | 良好     | 关注   |
| 王五 | 3班  |   68 | 良好     | 关注   |
| 周六 | 3班  |   58 | 不及格   | 关注   |
| 南北 | 3班  |    0 | 缺考     | 关注   |
+------+------+------+----------+--------+
17 rows in set (0.00 sec)

二、子查询

 子查询,顾名思义就是在语句中嵌套select查询语句

可以嵌套的地方:

select 之后

from之后

where 之后


1、select 之后

#查询学生的班主任的姓名

mysql> select
    -> st.stname,st.stclass,
    -> (select te.tename from t_teacher  te where te.teclass=st.stclass) as teacher
    -> from
    -> t_student st;
+--------+---------+---------+
| stname | stclass | teacher |
+--------+---------+---------+
| 赵钱   | 1班     | 点赞    |
| 王五   | 3班     | 关注    |
| 上下   | 1班     | 点赞    |
| 钱七   | 1班     | 点赞    |

| 秋     | 3班     | 关注    |
| 孙李   | 3班     | 关注    |
+--------+---------+---------+
26 rows in set (0.00 sec)

2、from之后

将form之后的select的查询结果当成一张表,然后进行表的连接查询就可以了

#查询每个班的平均成绩的成绩等级

mysql> select
    -> st.stclass,st.avgmath,g.grade
    -> from
    -> (select stclass,avg(stmath) as avgmath from t_student group by stclass) st
    -> left join
    -> t_grade g
    -> on
    -> st.avgmath between g.min and g.max;
+---------+---------+-------+
| stclass | avgmath | grade |
+---------+---------+-------+
| 1班     | 77.0000 | 良好  |
| 3班     | 76.7143 | 良好  |
| 2班     | 74.5556 | 良好  |
+---------+---------+-------+
3 rows in set (0.04 sec)

3、where之后

间接在where中使用聚合函数

#查询成绩在平均分以上的学生

mysql> select
    -> stname,stmath
    -> from
    -> t_student
    -> where
    -> stmath>(select avg(stmath) from t_student);
+--------+--------+
| stname | stmath |
+--------+--------+
| 赵钱   |     78 |
| 钱七   |     93 |
| 左右   |     88 |
| 周三   |     77 |
| 周四   |     94 |
| 夏     |     82 |
| 张三   |     87 |
| 甲乙   |     88 |
| 前后   |     93 |
| 周五   |     99 |
| 冷烬   |    100 |
| 周二   |     78 |
| 丙丁   |     91 |
| 秋     |     89 |
+--------+--------+
14 rows in set (0.00 sec)

未完待续。。。。。。。。。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冷烬亿下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值