多表查询

select * from BONUS;
select * from DEPT;
select * from EMP;
select * from SALGRADE;
BONUS表 ENAME JOB SAL COMM

DEPT表 DEPTNO DNAME LOC
1 10 ACCOUNTING NEW YORK
2 20 RESEARCH DALLAS
3 30 SALES CHICAGO
4 40 OPERATIONS BOSTON

EMP表 EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
1 7369 SMITH CLERK 7902 1980/12/17 800.00 20
2 7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
3 7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
4 7566 JONES MANAGER 7839 1981/4/2 2975.00 20
5 7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
6 7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7 7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
8 7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20
9 7839 KING PRESIDENT 1981/11/17 5000.00 10
10 7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
11 7876 ADAMS CLERK 7788 1987/5/23 1100.00 20
12 7900 JAMES CLERK 7698 1981/12/3 950.00 30

SALGRADE表 GRADE LOSAL HISAL
1 1 700 1200
2 2 1201 1400
3 3 1401 2000
4 4 2001 3000
5 5 3001 9999

xlsx格式转换为HTML格式: http://pressbin.com/tools/excel_to_html_table/index.html

一:笛卡尔积

/*
多表查询:笛卡尔积
select * from 表1,表2 */ select * from emp,dept; --56条数据中有没有意义的结果,所以需要加条件筛选有意义的结果
select * from emp,dept where emp.DEPTNO =DEPT.DEPTNO;
select * from emp e1 ,dept d1 where e1.DEPTNO =d1.DEPTNO; --别名,简化sql语句

二:内联接

/*
内联接:
隐式内联接:
等值内联接: where e1.DEPTNO =d1.DEPTNO
不等值内联接:where e1.DEPTNO <> d1.DEPTNO 无意义,不用
自联接: 显示内联接:
select * from 表1 inner join 表2 on 连接条件 inner 关键字可以省略 */ select *from emp; select EMPNO || '员工编号',ENAME || '员工姓名',JOB || '职业',MGR || '经理编号',HIREDATE ||'雇佣日期',SAL,COMM,DEPTNO ||'部门编号' from emp; --可以查出所有信息
--查询员工编号,员工姓名,经理的编号,经理的姓名 :通过上面可以发现所有的信息都在emp表中
select * from emp e1,emp m1 where e1.mgr = m1.empno ;
select e1.empno,e1.ename,m1.mgr,m1.ename from emp e1,emp m1 where e1.mgr = m1.empno ; --查询员工编号,员工姓名,员工的部门名称,经理的编号,经理的姓名
select * from dept; --查询一下部门表
select e1.empno,e1.ename,d1.dname,m1.mgr,m1.ename
from emp e1,emp m1,dept d1
where e1.mgr = m1.empno
and e1.deptno=d1.deptno; --注意and联接
--查询员工编号,员工姓名,员工的部门名称,经理的编号,经理的姓名,经理的部门
select e1.empno,e1.ename,d1.dname,m1.mgr,m1.ename ,d2.dname
from emp e1,emp m1,dept d1,dept d2
where e1.mgr = m1.empno
and e1.deptno=d1.deptno
and m1.deptno=d2.deptno;
--总结:员工的部门:员工表与部门表,经理的部门:经理表与部分表 --查询员工编号,员工姓名,员工的工资等级,员工的部门名称,经理的编号,经理的姓名,经理的部门
select * from SALGRADE;
select e1.empno,e1.ename,s1.grade,d1.dname,m1.mgr,m1.ename ,d2.dname
from emp e1,emp m1,dept d1,dept d2 ,SALGRADE s1
where e1.mgr = m1.empno
and e1.deptno=d1.deptno
and m1.deptno=d2.deptno
and e1.sal between s1.losal and s1.hisal; --给工资等级取中文名 1对应一级,2对应二级,,,
select * from SALGRADE; select e1.empno,e1.ename,
d1.dname,m1.mgr,m1.ename ,d2.dname,
case s1.grade
when 1 then '一级'
when 2 then '二级'
when 3 then '三级'
when 4 then '四级'
else
'五级'
end "等级"
from emp e1,emp m1,dept d1,dept d2 ,SALGRADE s1
where e1.mgr = m1.empno
and e1.deptno=d1.deptno
and m1.deptno=d2.deptno
and e1.sal between s1.losal and s1.hisal; --建议把工资等级放最后
-- end 后面取别名 --查询员工部门和员工部分所在的位置
select * from emp e1,dept d1 where e1.DEPTNO=d1.deptno; --先查出所有字段 select e1.ename,d1.loc
from emp e1,dept d1
where e1.DEPTNO=d1.deptno; --显示内联接:
--查询员工部门和员工部分所在的位置
select * from emp e1 inner join dept d1 on e1.deptno=d1.deptno;
select e1.ename,d1.loc from emp e1 inner join dept d1 on e1.deptno=d1.deptno; /*
外连接:
左外连接:left outer joinL:左表中所有数据,如果右表中没有对应记录,就显示为空
右外连接:right ouoter join:右表中所有数据,如果左表中没有对应记录,就显示为空
outer关键字可以省略 oracle中的外连接:(+):如果没有对应的值就加上空值
select * from emp e1 inner join dept d1 on e1.deptno=d1.deptno; --内连接
select * from emp e1,dept d1 where e1.deptno=d1.deptno(+); --类似于左外连接
select * from emp e1,dept d1 where e1.deptno(+)=d1.deptno; --类似于右外连接
*/ --左外连接
select * from emp;
select * from dept ;
select * from emp e1 left outer join dept d1 on e1.deptno=d1.deptno; --注意别少了join和on关键字

三:子查询

/*
子查询:查询语句中嵌套查询语句 */
1:查询最高工资的员工信息
--查询出最高工资
select max(sal) from emp;
--工资等于最高工资的员工信息
select * from emp where sal = (select max(sal) from emp); --查询比雇员7654工资高,同时和7788从事相同工作的员工信息
--1:雇员7654的工资
select sal from emp where EMPNO=7654; --1250.00
--2:7788相同工作
select job from emp where EMPNO=7788; --ANALYST
--3:同时and
select * from emp where sal > (select sal from emp where EMPNO=7654) and job = (select job from emp where EMPNO=7788); --查询每个部门最低工资的员工信息和他所在的部门信息 --重点
--1:查询每个部门最低工资--group by分组统计
select DEPTNO,min(sal) minsal from emp group by DEPTNO; --当成t1表
--2:员工工资等于他所处部门的最低工资
select * from emp e1,t1 where e1.deptno = t1.deptno and e1.sal = t1.minsal; select *
from emp e1,(select DEPTNO,min(sal) minsal from emp group by DEPTNO) t1
where e1.deptno = t1.deptno and e1.sal = t1.minsal;
--3:查询部门相关信息
select *
from emp e1,(select DEPTNO,min(sal) minsal from emp group by DEPTNO) t1 ,
dept d1
where e1.deptno = t1.deptno and e1.sal = t1.minsal
and e1.deptno=d1.deptno;

四:条件查询

/*
in
not in
any
all */ 1:查询所有领导的信息
--查询所有经理的编号
select mgr from emp; --有空值
select distinct mgr from emp; --去重
--结果 --员工编号在经理编号中就是经理
select * from emp e1 where e1.empno in (select mgr from emp); 2:查询不是领导的信息
select * from emp e1 where e1.empno not in (select mgr from emp); --因为有空值,所以无输出,空值问题 select * from emp e1 where e1.empno not in (select mgr from emp where mgr is not null); --正确 --exists(查询语句):数据量非常大的时候,非常高效.当查询语句有结果,返回true,否则返回false --查询有员工的部门信息
select * from emp;
select * from dept;
select * from dept d1 where exists(select * from emp e1 where e1.deptno = d1.deptno);

五:rownum

--找到员工表中工资最高的前三名
select * from emp order by sal desc ; --不正确,没有提取前3列
/* rownum:伪列,用来表示行号,是oracle中特有的,默认值是1,在查询出结果之后再添加1。
rownum不做大于号判断,可以做小于号判断 mysql使用limit关键字 */
select rownum,e1.* from emp e1; --注意查看rownum列 --查询rownum大于2的所有记录
select rownum,e1.* from emp e1 where rownum >2 ; --没有任何记录,rownum从1开始,查询一条,当前rownum为1,小于2,没有记录 --查询rownum大于等于1的所有记录
select rownum,e1.* from emp e1 where rownum >=1 ; --所有记录 --查询rownum小于6的所有记录
select rownum,e1.* from emp e1 where rownum <6 ; --rownum排序会打乱
--SQL的执行顺序:from, where, group by, having, select [rownum],order by --找到员工表中工资最高的前三名
select * from emp order by sal desc ; 可以把它当成一张表,重新查询,重新生成新的rownum
select rownum,t1.* from (select * from emp order by sal desc ) t1;
select rownum,t1.* from (select * from emp order by sal desc ) t1 where rownum <= 3; --最终结果 --找到员工表中薪水大于本部门平均薪水的员工
--1:找到所有部门的平均薪水
select DEPTNO,floor(avg(SAL)) FROM emp group by DEPTNO; --把它的结果当成新表他t1
--2:员工工资 >本部门平均工资
select * FROM emp e1,(select DEPTNO, floor(avg(SAL)) avgsal FROM emp group by DEPTNO) t1 where e1.deptno =t1.DEPTNO and e1.sal > t1.avgsal;
--方法二:关联子查询
SELECT * FROM emp e WHERE e.sal > (SELECT avg(sal) FROM emp e2 group by deptno having e.deptno =e2.deptno) --统计每年入职的员工个数
--只统计年
select hiredate from emp;
select to_char(hiredate,'yyyy') from emp;
--分组统计
select to_char(hiredate,'yyyy') from emp group by to_char(hiredate,'yyyy') ; select to_char(hiredate,'yyyy'),count(1) from emp group by to_char(hiredate,'yyyy') ; --最终结果 --结果横竖倒立
|1987|1980|
| 2| 3 |
select to_char(hiredate,'yyyy') yy ,count(1) cc from emp group by to_char(hiredate,'yyyy') ;
--1.1
select
case yy when '1987' then 2 end xx
FROM (select to_char(hiredate,'yyyy') yy ,count(1) cc from emp group by to_char(hiredate,'yyyy')) ; --1.2 :end别名需要用双引号,单引号报错
select
case yy when '1987' then 2 end "1987"
FROM (select to_char(hiredate,'yyyy') yy ,count(1) cc from emp group by to_char(hiredate,'yyyy')) ; --1.3使用聚合函数sum,去除行记录的null值
select
sum (case yy when '1987' then cc end) "1987"
FROM (select to_char(hiredate,'yyyy') yy ,count(1) cc from emp group by to_char(hiredate,'yyyy')) ; --1.4 统计其它,举一反三
select
sum (case yy when '1987' then cc end) "1987",
sum (case yy when '1980' then cc end) "1980"
FROM (select to_char(hiredate,'yyyy') yy ,count(1) cc from emp group by to_char(hiredate,'yyyy')) ; --统计员工总数
select
sum(cc) "总数"
FROM (select to_char(hiredate,'yyyy') yy ,count(1) cc from emp group by to_char(hiredate,'yyyy')) ; --把每天员工入职个数和员工总数汇合在一起
select
sum (case yy when '1987' then cc end) "1987",
sum (case yy when '1980' then cc end) "1980",
sum (case yy when '1982' then cc end) "1982",
sum (case yy when '1981' then cc end) "1981",
sum(cc) "总数"
FROM (select to_char(hiredate,'yyyy') yy ,count(1) cc from emp group by to_char(hiredate,'yyyy')) ;

六:rowid的使用

--rowid:每行记录存放的真实物理地址
select rowid,e.* from emp e;
--例子
--去除表中重复数据
create table p(
name varchar2(10)
);
insert into p values('张三'); --执行3次
insert into p values('李四'); --执行4次
select rowid,p.* from p; --删除表中记录,只保留rowid最小的记录,一张表当两张表用
DELETE FROM p p1 WHERE rowid > (select min(ROWID) FROM p p2 where p1.name = p2.name);
select rowid,p.* from p;

七:分页查询

/*
oracle:rownum:分页查询
mysql: limit */ --查询员工表第6第-10的记录
select rownum hanghao ,emp.* from emp;
select * from (select rownum hanghao ,emp.* from emp) t1 WHERE t1.hanghao between 6 and 10;

八: 集合运算

/*
集合运算:
并集:将两个查询结果进行合并 union 去重和 union all 不去重
交集:
*/
--工资大于1500,或者20号部门以下的员工
select * from emp where sal > 1500 or deptno=20;
--工资大于1500的员工信息
select *from emp where sal > 1500;
--20号部门下的员工信息
select *from emp where deptno = 20;
--并集union
select *from emp where sal > 1500
union
select *from emp where deptno = 20; --9条记录,union去重
--并集union all
select *from emp where sal > 1500
union all
select *from emp where deptno = 20; --12条记录,Union all 不去重 --差集运算
--1981年入职的员工(不包括总裁和经理)
--1.1981年入职的员工
select * from emp where to_char(hiredate,'yyyy') =1981;
--1.2查询总裁和经理
select *from emp where job ='PRESIDENT' or job= 'MANAGER';
--差集运算
select * from emp where to_char(hiredate,'yyyy') =1981
minus
select *from emp where job ='PRESIDENT' or job= 'MANAGER';

oracle_多表查询02的更多相关文章

  1. Oracle_多表查询

    SQL多表查询 等值和不等值连接查询 从多个表中获取数据:如果在查询的时候,直接从多个表中获取数据.没有添加条件判断,会出现"笛卡尔积"错误 笛卡尔积错误 笛卡尔集会在下面条件下产 ...

  2. mysql,SQL标准,多表查询中内连接,外连接,自然连接等详解之查询结果集的笛卡尔积的演化

    先附上数据. CREATE TABLE `course` ( `cno` ) NOT NULL, `cname` ) CHARACTER SET utf8 NOT NULL, `ctime` ) NO ...

  3. 【T-SQL基础】01.单表查询-几道sql查询题

    概述: 本系列[T-SQL基础]主要是针对T-SQL基础的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础]02.联接查询 [T-SQL基础]03.子查询 [T-SQL基础 ...

  4. oracle 表查询(二)

    1.使用逻辑操作符号问题:查询工资高于500或者是岗位为manager的雇员,同时还要满足他们的姓名首字母为大写的J?select * from emp where (sal > 500 or ...

  5. SQL基本查询_单表查询(实验二)

    SQL基本查询_单表查询(实验二) 查询目标表结构及数据 emp empno ename job hiedate sal comn deptno 1007 马明 内勤 1992-6-12 4000 2 ...

  6. SQL基本查询_多表查询(实验三)

    SQL基本查询_多表查询(实验三) 题目要求(一) 针对emp.dept两表完成如下查询,并验证查询结果的正确性 使用显式内连接查询所有员工的信息,显示其编号.姓名.薪水.入职日期及部门名称: 使用隐 ...

  7. (六)Oracle 的 oracle表查询关键字

    参考:http://www.hechaku.com/Oracle/oracle_tables2.html 1.使用逻辑操作符号问题:查询工资高于500或者是岗位为manager的雇员,同时还要满足他们 ...

  8. day056-58 django多表增加和查询基于对象和基于双下划线的多表查询聚合 分组查询 自定义标签过滤器 外部调用django环境 事务和锁

    一.多表的创建 from django.db import models # Create your models here. class Author(models.Model): id = mod ...

  9. python 全栈开发,Day74(基于双下划线的跨表查询,聚合查询,分组查询,F查询,Q查询)

    昨日内容回顾 # 一对多的添加方式1(推荐) # book=Book.objects.create(title="水浒传",price=100,pub_date="164 ...

随机推荐

  1. mvc partialView断点调试问题

    mvc中的partialview 在前端f12调试时,默认看不到代码的.  在Js中加上debugger;  调试时会走到断点,多出个VM打头的局部视图页面.

  2. centos7 设置 tomcat 开机自启

    1.创建文件 # vi /etc/systemd/system/tomcat.service [Unit] Description=Tomcat8540 After=syslog.target net ...

  3. 阶段5 3.微服务项目【学成在线】_day05 消息中间件RabbitMQ_1.页面发布-需求分析

    先静态化,并存储到gridFS 然后,发消息给MQ,MQ接收到消息通知给所有监听他的Cms Client. Cms client从gridFS读取页面下载到自己的服务 业务流程如下:1.管理员进入管理 ...

  4. windows注册服务

    Windows服务是运行一些服务程序的较好方式(这些程序专门为各种功能提供服务,无操作界面,运行在后台),其创建方法也很简单,通过系统自带的sc命令即可方便的创建. sc命令创建Windows服务的方 ...

  5. PJzhang:ms17-010永恒之蓝漏洞在windows 2008R2中的复现

    猫宁!!! 参考: https://www.anquanke.com/post/id/86245 https://xz.aliyun.com/t/2536 https://www.cnblogs.co ...

  6. java 中 this 和 super 说明及在构造器中super()和this()相互调用执行顺序

    this this 表示当前对象 使用上细分的话,this有 this. 和this()的使用情况 ,下面我们开始细撸 this . 使用场景一: 在成员方法中,this.变量名 指带当前对象的变量, ...

  7. 通用 spring cloud 微服务模板

    说明文档 功能 1. 基于映射数据库一键生成 spring cloud 微服务 2. 通用 Controller ,无需编写代码即可完成基于数据库的服务 3. 动态多条件 CRUD + 分页 使用说明 ...

  8. HttpHelper帮助类

    public class HttpHelper { #region 预定义方变量 //默认的编码 private Encoding _encoding = Encoding.Default; //Po ...

  9. 如何在视图中启用thymeleaf

    1.在HTML标签中引入一个属性 <html xmlns:th="http://www.thymeleaf.org"> <!-- 引入xmlns:th属性才能启用 ...

  10. stat中的st_dev和st_rdev

    目录 stat中的st_dev和st_rdev title: stat中的st_dev和st_rdev date: 2019/11/27 21:04:25 toc: true --- stat中的st ...