MySQL多表连接查询

1.自连接查询

一个表 自己 与 自己 建立 连接 称为自连接或自身连接。 进行自连接就如同两个分开的表
一样,可以把一个表的某一行与同一表中的另一行连接起来。

//查询选学“数学”课程的成绩高于“88”号学生成绩的所有学生记录 并按成绩从高到低排列
   select x.* from sclass x,sclass y 
   where x.cno='数学' and x.degree>y.degree  
   and y.sno='88' and y.cno='数学'
   order  by  x.degree desc

这里写图片描述
2.外连接(outer join)

  • 左外连接(left join or left outer join)
    这里写图片描述
  • 右外连接(right join or right outer join)
    这里写图片描述
  • 完全外连接( full join or full outer join)
    这里写图片描述
    3.内连接(join or inner join) 连接条件就是主外键的关联
  • 不等值连接
    就是在关键字on后面的的匹配条件中通过>.<.>=.<=.!=等连接的。
  • 等值连接
    就是在关键字on后面的的匹配条件中通过“=”连接的。

  • 自然连接(natural join)
    自然连接是一种特殊的等值连接,它要求两个关系进行比较的分量必须是相同的属性组,并且在结果集中将重复属性列去掉。
    SQL:SELECT *FROM authors NATURAL JOIN publishers
    这里写图片描述
    结果如下:
    这里写图片描述
    这里写图片描述
    结果为(1、3、4)行,ABCD四列

等值连接与自然连接的区别:
自然连接是一种特殊的等值连接
1)等值连接中不要求相等属性值的属性名相同,而自然连接要求相等属性值的属性名必须相同,即两关系只有在同名属性才能进行自然连接。
2)等值连接不将重复属性去掉,而自然连接去掉重复属性,也可以说,自然连接是去掉重复列的等值连接。
3)事实上,我们一般使用的都是自然连接。

4.交叉连接(cross join) 笛卡尔积 m*n
这里写图片描述
5.合并查询(union)
- 合并是两个表的相加,连接是两个表的相乘
- 在合并中行的最大数量是和 ,而在连接中行的最大数量是积
- 关键字 union all,不加时自动去掉重复
- 关键字order by, 有且只有一个order by 子句并且必须将它放置语句的末尾
这里写图片描述

一同事在做读取数据时,碰到这样的疑惑,分别从两个表中读取数据,读取的字段不一样,但最后呈现的列都是一样的。能否有办法一次合并这两个表中的数据到前台进行输出呢?

先说一下涉及到的两个表: 考试表:ExamTB 涉及字段:EId int,EName varchar(50),SubjectId
int,EStartTime datetime 任务表:TaskTB 涉及字段:TId int,TName
varchar(50),SubjectId int,TStartTime datetime
解决方案:建立一张中间表,现将表一数据读进去,再将表二数据读进去,从中间表获取数据。

6.子查询
为什么使用子查询?
在进行多表查询时,为了避免对两个表进行笛卡尔积操作(数据量很大时,容易死机)。
先查询表中的数据量,如果MySQL可以接收,才能进行多表查询。如果接受不了,则用子查询。
子查询指在一个查询中嵌套了其他若干查询,即在where子句或from子句中包含另一个查询语句。
where子句中的子查询:返回值(单行单列、单行多列、单列多行)
from子句中的子查询:返回值(多行多列)
a.单行单列子查询
通常会包含比较运算符(=<>!=)

//查询成绩大于学号是1010214学生成绩的学生列表。
select * from  students  where  grade>(select grade from students where stuNum="1010214" )

b.单行多列子查询

//查询雇员表中(t_employee),工资和职位与小明一样的全部雇员信息
select  name,salary,job
from t_employee
where (salary,job)=(select salary,job from t_employee where name='小明'

c.多行单列子查询(IN . ANY . ALL . EXISTS)

  • 带有关键字 IN or NOT IN
 专业代号和专业表、学生信息表
 // 查询学生信息表中,专业代号在专业代号和专业表出现的所有记录

        select *
        from students
        where deptno  in (select deptno from dept);
  • 带有关键字ANY
=ANY:与IN的功能一样
 >ANY(>=ANY):比查询记录中最小的还要大于(大于等于)
<ANY(<=ANY):比查询记录中最大的还要小于(小于等于)
  • 带有关键字ALL
>ALL(>=ALL):比查询记录中最大的还要大于(大于等于)
<ALL(<=ALL):比查询记录中最小的还要小于(小于等于)
  • 带有关键字EXISTS
    查询部门表(t_dept)中的字段:部门编号(deptno)、部门名称(deptname),如果该部门没有员工,则将其显示出来。
//先写子查询(部门编号与员工部门编号匹配的表)
SELECT * FROM t_employee a,t_dept c WHERE a.deptno=c.deptno)
//假定部门编号确定,如果有员工,则有返回记录,反之没有。
select * from t_dept c where NOT EXISTS
(select * from t_employee where deptno=c.deptno)
//该查询首先遍历部门表中的记录,如遍历到第一条记录,然后吧部门编号(deptno)传给子查询,如果子查询有返回记录,条件为真,则显示当前父查询的记录。反之不显示。

d.返回值为多行多列(a jion this or from this)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值