合并结果集、连接查询、子查询、自连接
把两个select语句的查询结果合并到一起
select * from 表1 union select * from 表2;
select * from 表1 union all select * from 表2;
-- 先建个表
create table A(name varchar(10), score int);
create table B(name varchar(10), score int);
-- 插入数据
insert into A values('a',10),('b',20),('c',30);
insert into B values('a',10),('b',20),('d',40);
-- union查询
select * from A
union
select * from B;
-- union all查询
select * from A
union all
select * from B;
跨表查询,需要关联多个表进行查询;同时查询两个表,出现的就是笛卡尔集结果。
select * from stu, score;
select * from stu st,score sc;
-- st表示stu表,sc表示score表
1. 在查询时要把主键和外键保持一致;
2. 主表当中的数据参照子表当中的数据;
3. 原理逐行判断,选择对应数据。
select * from stu st,score sc where st.sid = sc.sid;
-- 查看对应学号的学生信息和成绩
-- 将学号相同的学生数据连接在一起
--内连接
SELECT * FROM stu st INNER JOIN score sc ON st.sid = sc.sid;
-- 查询结果同(多表联查)
select * from stu st, score sc where st.sid = sc.sid;
-- 补充条件连接查询,查询对应学号,成绩大于60分的男生
SELECT st.sno,st.`sname`,st.sex,sc.score FROM students st
JOIN score sc
ON st.sno = sc.sid
WHERE sc.score > 60
AND st.sex ='nan';
INNER JOIN等价于 JOIN;
ON后只写主外键;
有条件写WHERE;
还有条件加AND。
SELECT * FROM students st LEFT OUTER JOIN score sc ON st.sno = sc.sid;
SELECT * FROM students st RIGHT OUTER JOIN score sc ON st.sno = sc.sid;
SELECT st.`sname`,sc.score,c.tname
FROM students st,score sc,course c
WHERE st.sno = sc.sid
AND sc.cid = c.cid;
SELECT st.`sname`,sc.score,c.tname
FROM students st
JOIN score sc ON st.sno = sc.sid
JOIN course c ON sc.cid = c.cid;
-- 建表emp
create table `emp`(
`empno` int(11) not null,
`ename` varchar(255) default null,
`job` varchar(255) default null,
`mgr` varchar(255) default null,
`hiredate` date default null,
`salary` decimal(10,0) default null,
`comm` double default null,
`deptno` int(11) default null,
primary key (`empno`)
) engine = innoDB default charset = utf8;
-- 建表dept,使用comment可以在语句里加注释
create table `dept`(
`deptno` bigint(2) not null auto_increment comment '表示部门编号,有两位数字所组成',
`dname` varchar(14) default null comment '部门名称,最多由14个字符所组成',
`local` varchar(13) default null comment '部门所在的位置',
primary key (`deptno`)
) engine = innoDB auto_increment = 41 default charset = utf8;
-- 建表salgrade
create table `salgrade`(
`grade` bigint(11) not null auto_increment comment '工资等级',
`lowSalary` int(11) default null comment '此等级的最低工资',
`highSalary` int(11) default null comment '此等级的最高工资',
primary key (`grade`)
) engine = innoDB auto_increment = 6 default charset = utf8;
-- 给这三个表填上数据
查询所有员工的姓名,工资,所在部门的名称以及工资的等级
-- 99法
select e.ename, e.salary, d.dname, g.grade
from emp e, dept d, salgrade g
where e.deptno = d.deptno
and e.salary >= g.lowSalary and e.salary <= g.highSalary;
-- 内连接法
select e.ename, e.salary, d.dname, g.grade from emp e
join dept d on e.deptno = d.deptno
join salgrade g on e.salary between g.lowSalary and g.highSalary;
select * from emp NATURAL JOIN dept;
以共有的deptno进行连接
navicat中query builder(查询创建工具):查看约束关系
一个select语句中包含另一个完整的select语句,即一个查询中出现了两个或两个以上的select。
select ename,deptno from emp
where deptno = (select deptno from emp where ename = 'cv');
select ename from
(select ename, salary, deptno from emp where deptno = 1002) s
where s.salary>2000;
-- s代指查出来的中间表
select ename, salary from emp
where salary > (select salary from emp where ename = 'qw' );
select ename, salary from emp
where salary > (select max(salary) from emp where deptno = 1002);
select * from emp
where (job,salary)
in (select job,salary from emp where ename = 'gh');
-- 等同于
select * from emp e,(select job,salary from emp where ename = 'gh') r
where e.job = r.job and e.salary = r.salary;
有两个及以上直接下属的员工信息
思路:以管理者编号mgr分组并显示分组信息,组内数量
-- 第一步,每个管理者管理人数
select mgr,group_concat(mgr),count(mgr) from emp group by mgr;
-- 第二步,查询(管理者编号mgr,员工编号empno)
SELECT * FROM emp
WHERE empno in (SELECT mgr FROM emp GROUP BY mgr HAVING count(mgr)>=2);
SELECT e.ename,e.salary,d.dname,d.`local`
FROM emp e,dept d
WHERE e.empno = 5 and e.deptno=d.deptno;
SELECT e1.empno, e1.ename, e2.empno,e2.ename
FROM emp e1, emp e2
where e1.empno = 7
and e1.mgr = e2.empno;