MySQL--复合查询、表的内外连接(*****)

**************************************文中所用表为oracle 9i 的经典测试表************************************************

回顾基本查询

  • 查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写J
select ename,sal,job from emp where (sal>500 or job='MANAGER') and ename like 'J%';
  • 按照部门号升序而雇员的工资降序排序
 select deptno,ename,sal from emp order by deptno,sal desc;
  • 显示工资高于平均工资的员工
 select ename,job,sal from emp where sal>(select avg(sal) from emp);
  • 显示每个部门的平均工资和最高工资
 select deptno,avg(sal),max(sal) from emp group by deptno;
  • 显示平均工资低于2000的部门号和它的平均工资
select deptno,avg(sal) from emp group by deptno having avg(sal)<2000;
  • 显示每种岗位的雇员总数,平均工资
 select job,count(*),avg(sal) from emp group by job;

多表查询

  • 显示雇员名、雇员工资以及所在部门的名字
select emp.ename,emp.sal,dept.dname from emp,dept where emp.deptno=dept.deptno;
  • 显示部门号为10的部门名,员工名和工资
select dept.dname,emp.ename,emp.sal from emp,dept where emp.deptno=dept.deptno and emp.deptno=10;
  • 显示各个员工的姓名,工资,及工资级别
select emp.ename,emp.sal,salgrade.grade from emp,salgrade where sal between salgrade.losal and salgrade.hisal;

自连接

自连接是指在同一张表连接查询

  • 显示员工FORD的上级领导的编号和姓名

子查询

select emp.empno,emp.ename from emp where empno=(select mgr from emp where ename='FORD');

自查询(使用到表的别名,可以认为worker和leader都是一张独立的emp表)

select leader.empno,leader.ename from emp worker,emp leader where leader.empno=worker.mgr and worker.ename='FORD';

子查询

子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询

单行子查询(返回单列,单行数据)

  • 显示SMITH同一部门的员工
 select * from emp where deptno=(select deptno from emp where ename = 'SMITH');

多行子查询(返回单列多行数据)

  • 查询和10号部门的工作相同的雇员的名字,岗位,工资,部门号,但是不包含10自己的
 select ename,job,sal,deptno from emp where job in(select distinct job from emp where deptno=10) and deptno!=10;
  • 显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号
select ename,sal,deptno from emp where sal>(select max(sal) from emp where deptno=30);

all关键字:

select ename,sal,deptno from emp where sal>all(select sal from emp where deptno=30);
  • 显示工资比部门30的任意员工的工资高的员工的姓名、工资和部门号
 select ename,sal,deptno from emp where sal>(select min(sal) from emp where deptno=30);

any关键字:

select ename,sal,deptno from emp where sal>any(select sal from emp where deptno=30);

多列子查询(返回多个列数据)

  • 查询和SMITH的部门和岗位完全相同的所有雇员,不含SMITH本人
select ename,deptno,job from emp where (deptno,job)=(select deptno,job from emp where ename='SMITH') and ename!='SMITH';

在from子句中使用子查询语句

  • 显示高于自己部门平均工资的员工的姓名、部门、工资、平均工资
select ename,deptno,sal,avg(sal) from emp,(select avg(sal) avgsal,deptno dt from emp group by deptno) temp where emp.sal>temp.avgsal and emp.deptno=temp.dt;

注意:将from中的子句查询结果当做一个临时表来用,取名为temp。

  • 查找每个部门工资最高的人的姓名、工资、部门、最高工资
select emp.deptno,emp.ename,emp.sal,maxsal from emp,(select max(sal) maxsal,deptno from emp group by deptno) temp where emp.deptno=temp.deptno and emp.sal=temp.maxsal;
  • 显示每个部门的信息(部门名,编号,地址)和人员数量

方法一:多表查询

select dept.deptno,dept.dname,dept.loc,count(*) from emp,dept where emp.deptno=dept.deptno group by dept.deptno,dept.dname,dept.loc;

方法二:子查询

 select dept.deptno,dept.dname,mycnt,dept.loc from dept,(select count(*) mycnt,deptno from emp group by deptno) temp where dept.deptno=temp.deptno;

表的内连接

内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选(前面的查询都是内连接)。

  • 显示SMITH名字和部门名称
 select ename,dname from emp,dept where emp.deptno=dept.deptno and ename='SMITH';

用标准的内连接写法

select ename,dname from emp inner join dept on emp.deptno=dept.deptno and ename='SMITH';

表的外连接 --- 左外连接、右外连接

左外连接:如果联合查询,左侧的表完全显示我们就说是左外连接。

select 字段名 from 表名1 left join 表名2 on 连接条件;

右外连接:如果联合查询,右侧的表完全显示我们就说是右外连接。

select 字段 from 表名1 right join 表名2 on 连接条件;

  (表1 left join 表2)就相当于(表2 right join 表1)

例:建立如下表

create table stu (id int, name varchar(30)); -- 学生表
insert into stu values(1,'jack'),(2,'tom'),(3,'kity'),(4,'nono');
create table exam (id int, grade int); -- 成绩表
insert into exam values(1, 56),(2,76),(11, 8);
  • 查询所有学生的成绩,如果这个学生没有成绩,也要将学生的个人信息显示出来

左外连接:

select * from stu left join exam on stu.id=exam.id;

右外连接:

select * from exam right join stu on exam.id=stu.id;

猜你喜欢

转载自blog.csdn.net/Sun_GLL/article/details/86488595
今日推荐