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)