oracle_多表查询02
多表查询
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的更多相关文章
- Oracle_多表查询
SQL多表查询 等值和不等值连接查询 从多个表中获取数据:如果在查询的时候,直接从多个表中获取数据.没有添加条件判断,会出现"笛卡尔积"错误 笛卡尔积错误 笛卡尔集会在下面条件下产 ...
- mysql,SQL标准,多表查询中内连接,外连接,自然连接等详解之查询结果集的笛卡尔积的演化
先附上数据. CREATE TABLE `course` ( `cno` ) NOT NULL, `cname` ) CHARACTER SET utf8 NOT NULL, `ctime` ) NO ...
- 【T-SQL基础】01.单表查询-几道sql查询题
概述: 本系列[T-SQL基础]主要是针对T-SQL基础的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础]02.联接查询 [T-SQL基础]03.子查询 [T-SQL基础 ...
- oracle 表查询(二)
1.使用逻辑操作符号问题:查询工资高于500或者是岗位为manager的雇员,同时还要满足他们的姓名首字母为大写的J?select * from emp where (sal > 500 or ...
- SQL基本查询_单表查询(实验二)
SQL基本查询_单表查询(实验二) 查询目标表结构及数据 emp empno ename job hiedate sal comn deptno 1007 马明 内勤 1992-6-12 4000 2 ...
- SQL基本查询_多表查询(实验三)
SQL基本查询_多表查询(实验三) 题目要求(一) 针对emp.dept两表完成如下查询,并验证查询结果的正确性 使用显式内连接查询所有员工的信息,显示其编号.姓名.薪水.入职日期及部门名称: 使用隐 ...
- (六)Oracle 的 oracle表查询关键字
参考:http://www.hechaku.com/Oracle/oracle_tables2.html 1.使用逻辑操作符号问题:查询工资高于500或者是岗位为manager的雇员,同时还要满足他们 ...
- day056-58 django多表增加和查询基于对象和基于双下划线的多表查询聚合 分组查询 自定义标签过滤器 外部调用django环境 事务和锁
一.多表的创建 from django.db import models # Create your models here. class Author(models.Model): id = mod ...
- python 全栈开发,Day74(基于双下划线的跨表查询,聚合查询,分组查询,F查询,Q查询)
昨日内容回顾 # 一对多的添加方式1(推荐) # book=Book.objects.create(title="水浒传",price=100,pub_date="164 ...
随机推荐
- 蜗牛圈圈-时尚智能的运动计时App
Duang! 各类运动爱好者的福音来啦! 蜗牛圈圈-最智能的圈速计时助手 扫描二维码下载体验 [产品简介] -蜗牛圈圈是一款专业的圈速计时工具,帮助您获得整个运动过程中的各项数据,保存记录,分享激情. ...
- Flask 生成下载文件
1 后台程序直接生成文件内容 from flask import make_response @app.route('/testdownload', methods=['GET']) def test ...
- Git 中无法忽略 .xcuserstate 的解决方法
1.查看代码变化git status 2.接着输入 git rm –cached 刚才复制的地址 ,如下.git rm --cached RxSwift/Rx.xcodeproj/xcuserdata ...
- busybox中memdev的使用方法
busybox中已经集成了devmem工具,你可以配置busybox即可. 在busybox的杂项中找到: CONFIG_USER_BUSYBOX_DEVMEM: devmem is a small ...
- Tomcat发布项目
WEB项目的目录结构 演示动态项目的创建 把项目打包成war包: 进入这个项目中,使用命令: jar cvf aaa.war * 发布动态项目的三种方式: 1. 直接复制项目到webapps下 2. ...
- 深入理解Flink ---- End-to-End Exactly-Once语义
上一篇文章所述的Exactly-Once语义是针对Flink系统内部而言的. 那么Flink和外部系统(如Kafka)之间的消息传递如何做到exactly once呢? 问题所在: 如上图,当sink ...
- php开启短标签与<?xml version="1.0" encoding="UTF-8"?>冲突
前两天写了个生成mapsite的源码,想提交到百度和谷歌,在本地测试一点问题都没有,但是在服务器上就显示500错误 最后废了九牛二虎之力,终于可以设置iis直接显示出错信息. 也搞懂了问题所在,默认服 ...
- centos6.x一直停留在进度条的问题
由于屏幕关闭加上长时间没有操作可能导致centos进行深度休眠,此时只能通过电源键来强制重启.可以通过修改X11的配置来禁止休眠,配置文件为/etc/X11/xorg.conf,注意修改此文件前记得备 ...
- iframe高度自适应方法
<iframe width="100%" id="tbbrecommend" name="tbbrecommend" src=&quo ...
- mysql写存储过程根据时间变化增加工龄
在工作中遇到要程序根据时间自动增加工龄的需求. php没办法自己发起请求,又不想在服务器上写计划任务crontab,通过用户请求来更改又不能保证用户会去操作. 用数据库的存储过程和事件来完成. 数据库 ...