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 ...
随机推荐
- java实现磁盘先来先服务算法
package demo; import java.awt.List; import java.util.ArrayList; import java.util.Arrays; public clas ...
- SpringMVC返回Map类型转换成JSON失败
错误信息:WARN DefaultHandlerExceptionResolver:380 - Failed to write HTTP message: org.springframework.ht ...
- 使用idea进行activiti工作流开发入门学习
1.安装插件 在idea里面,activiti的插件叫actiBPM,在插件库里面把它安装好,重启idea就行了. 2.新建一个maven项目,并更改pom.xml.pom中依赖如下: <?xm ...
- linux 查看网络流量命令
转: linux 查看网络流量命令 2019年01月31日 14:22:00 weixin_33894992 阅读数 893 sar命令参数很多,有时间man一下. -n参数很有用,他有6个不同的 ...
- 阶段5 3.微服务项目【学成在线】_day05 消息中间件RabbitMQ_10.RabbitMQ研究-工作模式-路由工作模式介绍
队列在绑定交换机的时候可以指定routingKey, 路由模式: 1.每个消费者监听自己的队列,并且设置routingkey. 2.生产者将消息发给交换机,由交换机根据routingkey来转发消息到 ...
- 反向代理远端 单台tomcat 使用域名代理
.环境 nginx 10.1.1.161 公网:123.58.251.166 tomcat 10.1.1.103 .远端tomcat 配置 [root@host---- ~]# netstat -tn ...
- CentOS7.5使用RPM包安装MySQL5.7.22
参考:https://blog.csdn.net/sevenkoala/article/details/76163853 1,安装环境查看 2,下载安装rpm包 下载地址:https://downlo ...
- python如何发布自已pip项目
python如何发布自已pip项目前言因为自已平时会把一个常用到逻辑写成一个工具python脚本,像关于时间字符串处理,像关于路径和文件夹遍历什么的工具.每一次新建一个项目的时候都要把这些工具程序复制 ...
- C++中使用OPENCV对深度学习的特征图进行可视化
//需要先在运行目录下创建文件夹opencv_layers #include <iostream> #include <unistd.h> #include <openc ...
- ElasticSearch 获取es集群信息
参考博客:https://www.cnblogs.com/phpshen/p/8668833.html es集群信息有些版本下如果证书过期就会查不到,有些版本貌似不需要,提供一个据说不需要证书的版本的 ...