Oracle 数据库
一 关键词的理解
1 数据文件
数据文件是数据库的物理存储单位。数据库的数据是存储再表空间中的,真正是在其一个或者多个数据文件中,而一个表空间可以由一个或者多个数据文件组成,一个数据文件只能属于一个表空间,一旦数据文件被加入其一个表空间中,就不能删除这个文件,如果要删除其这个数据文件,只能删除其所属于的表空间才行。
2 表空间
表空间是oracle对物理数据库上相关数据文件(ORA或者DBF文件)的逻辑映射,一个数据库在逻辑上被划分成一个到若干个表空间,每个表空间包含了在逻辑上相关联的一组结构。每个数据库至少有一个表空间(称为之system表空间)。
每个表空间由同一个磁盘上的一个或者多个文件按组成,这些文件叫做数据文件,一个数据文件只能属于一个表空间。
(段,区,数据块,磁盘块)
3 用户
用户是在实例下建立的,不同的实例中可以创建相同名字的用户。
表的数据,是用户放入其中一个表空间的,而这个表空间会随机把这些表数据放入到一个或者多个数据文件中。
由于oracle的数据库不是普通的概念,oracle是有用户和表空间对数据进行管理和存放的,但是表不是有表空间去查询的,而是由用户去查的。因为不同用户可以在同一个表空间建立同一个名字的表,这里区分就是用户。
实例 ----- 用户(LHB) ----- 表空间(dbf ora)---(每个表随机存储在一个或者多个dbf/ora)
4 Scott 用户和Hr 用户
它们都是初始的用户 , 可以上网查看到他们有着不同的表。
二 基本查询
1 sql 简介
DML 数据库操作语言:其语句包括动词 INSERT UPDATE 和DELETE
DDL 数据库定义语言 create和DROP
DCL (数据库控制语言) GRANT 或REVOKE 确定单个用户和用户组对数据库对象的访问
别名中,有没有双引号的区别就在于别名中有没有特殊的符号或者关键字。
三 单行函数
1 什么是SQL的函数
输入(参数1,2,3)-------》 函数 ---------》输出结果,函数可以没有参数,但是必须要有返回值。
2 函数分为 单行函数 和 多行函数
单行函数: 字符 数值 转换 通用 日期 条件表达式
2.1 字符函数:
大小写控制函数:LOWER UPPER INITCAP
字符控制函数: CONCAT(字符连接函数 可以使用 ||) SUBSTR TRIM REPLACE LENGTH
2.3 条件表达式:在SQL语句中使用 if else then
例如:case ..... end decode
四 多行函数:
分组函数作用于一组数据,并对一组数据返回一个值,也叫组函数,组函数会忽略掉空值,NVL 函数使分组函数无法忽略空值。
AVG() COUNT() SUM() MAX() MIN() NVL(com,0) 如果参数一 为null 则默认为参数二 ,字符串的拼接用||来进行拼接,被拼接的字符串,通常使用单引号,双引号通常用在别名上面的 。Concat(‘姓名:’,snam) 做字符串的拼接 在mysql 和oracle中都有使用。
五:oracle数据库实例
数据库 ----》数据库实例------》表空间-----》数据文件
通常情况下 Oracle 数据库只会有一个实例ORCL
Oracle :创建表空间,创建用户,用用户去创建表。
Oracle 是多用户的,mysql 是多数据库的 oracle数据库的安全级别高。
Select 1+1 在oracle 报错 ,(要带上表名:+ from dual 虚表用来补充语法结构的)在mysql 中 = 2;
去除重复的数据 distinct
条件查询: where 比较运算符 逻辑预算 关系运算符 其他的预算符 like between.....and
模糊查询:............like ‘%/%%’ escape ‘/’ 特殊字符进行转意
排序 :ASC(升序) Desc(降序)
排序null 问题的注意 nulls first (这是默认的情况下 也可以是nulls last)
六基本查询(操作实例演示)
别名查询中 (别名)不能有特殊 ,如果有就要用到双引号。
select * from tab;
数据库 ---> 数据库实例 ---> 表空间(逻辑单位)(用户) ---> 数据文件(物理单位)
地球 ---> 一个国家 ---> 省份(逻辑单位)(公民) ---> 山川河流(物理单位)
通常情况下,ORacle数据库只会有一个实例ORCL,
新建一个项目:
MYSQL : 创建一个数据库,创建相应的表
Oracle: 创建一个表空间,创建用户,用户去创建表
Oracle和MYSQL的差别
Oracle是多用户的, MYSQL是多数据库的
1. 遵循SQL标准
2. 不同厂商,不同的数据库产品,但是有自己的方言
3. 使用自己的方言,也能够完成相同的功能
4. Oracle安全级别要高,MYSQL开源免费
基本查询:
SQL : 结构化查询语言
请听题: 请说一下SQL的分类以及每类常见的操作符都有哪些
四类:
DDL : 数据定义语言 create alter drop truncate
DML : 数据操纵语言 insert update delete
DCL : 数据控制语言 安全 授权 grant revoke
DQL : 数据查询语言 select from子句 where子句
查询语句的结构:
select [列名] [*] from 表名 [where 条件] [group by 分组条件] [having 过滤] [order by 排序]
select * from emp;
select 1+1; --在Oracle等于报错 ,在MYSQL中输出结果是2
dual : oracle中的虚表 ,伪表, 主要是用来补齐语法结
select 1+1 from dual;
select * from dual;
select 1 from emp;
--直接写一个常量比写 * 要高效
select count(1) from emp;
select count(*) from emp;
别名查询: 使用as 关键字, 可以省略
别名中不能有特殊字符或者关键字, 如果有就加双引号
select ename 姓名, sal 工资 from emp;
select ename "姓 名", sal 工资 from emp;
去除重复数据 distinct
多列去除重复: 每一列都一样才能够算作是重复
--单列去除重复
select distinct job from emp;
--多列去除重复的
select distinct job,deptno from emp;
--查询中四则运算
select 1+1 from dual;
--查询员工年薪 = 月薪* 12
select sal*12 from emp;
--查询员工年薪+奖金
select sal*12 + comm from emp;
--nvl 函数 : 如果参数1为null 就返回参数2
select sal*12 + nvl(comm,0) from emp;
注意: null值 , 代表不确定的 不可预知的内容 , 不可以做四则运算
字符串拼接:
java : + 号拼接
Oracle 特有的连接符: || 拼接
在Oracle 中 ,双引号主要是别名的时候使用, 单引号是使用的值, 是字符
concat(str1,str2) 函数, 在mysql和Oracle中都有
--查询员工姓名 : 姓名:SCOTT
select ename from emp;
--使用拼接符
select '姓名:' || ename from emp
--使用函数拼接
select concat('姓名:',ename) from emp;
条件查询 : [where后面的写法]
关系运算符: > >= = < <= != <>
逻辑运算符: and or not
其它运算符:
like 模糊查询
in(set) 在某个集合内
between..and.. 在某个区间内
is null 判断为空
is not null 判断不为空
--查询每月能得到奖金的员工信息
select * from emp where comm is not null;
--查询工资在1500--3000之间的员工信息
select * from emp where sal between 1500 and 3000;
select * from emp where sal >= 1500 and sal <= 3000;
--查询名字在某个范围的员工信息 ('JONES','SCOTT','FORD') in
select * from emp where ename in ('JONES','SCOTT','FORD');
_ 匹配单个字符
如果有特殊字符, 需要使用escape转义
模糊查询: like
% 匹配多个字符
--查询员工姓名第三个字符是O的员工信息
select * from emp where ename like '__O%';
--查询员工姓名中,包含%的员工信息
select * from emp where ename like '%\%%' escape '\';
select * from emp where ename like '%#%%' escape '#';
排序 : order by
升序: asc ascend
降序: desc descend
排序注意null问题 : nulls first | last
同时排列多列, 用逗号隔开
--查询员工信息,按照奖金由高到低排序
select * from emp order by comm desc nulls last;
--查询部门编号和按照工资 按照部门升序排序, 工资降序排序
select deptno, sal from emp order by deptno asc, sal desc;
函数: 必须要有返回值
单行函数: 对某一行中的某个值进行处理
数值函数
字符函数
日期函数
转换函数
通用函数
多行函数: 对某一列的所有行进行处理
max() min count sum avg
1.直接忽略空值
--统计员工工资总和
select sum(sal) from emp;
--统计员工奖金总和 2200
select sum(comm) from emp;
--统计员工人数 14
select count(1) from emp;
--统计员工的平均奖金 550 错误 2200/14 =
select avg(comm) from emp;
--统计员工的平均奖金 157.
select sum(comm)/count(1) from emp;
select ceil(sum(comm)/count(1)) from emp;
update emp set ename = 'TUR%NER' where ename = 'TURNER';
select * from emp;
--数值函数
select ceil(45.926) from dual; --46
select floor(45.926) from dual; --45
--四舍五入
select round(45.926,2) from dual; --45.93
select round(45.926,1) from dual; -- 45.9
select round(45.926,0) from dual; --46
select round(45.926,-1) from dual; --50
select round(45.926,-2) from dual; --0
select round(65.926,-2) from dual; --100
--截断
select trunc(45.926,2) from dual; --45.92
select trunc(45.926,1) from dual; -- 45.9
select trunc(45.926,0) from dual; --45
select trunc(45.926,-1) from dual; --40
select trunc(45.926,-2) from dual; --0
select trunc(65.926,-2) from dual; --0
--求余
select mod(9,3) from dual; --0
select mod(9,4) from dual; --1
--字符函数
-- substr(str1,起始索引,长度)
--注意: 起始索引不管写 0 还是 1 都是从第一个字符开始截取
select substr('abcdefg',0,3) from dual; --abc
select substr('abcdefg',1,3) from dual; --abc
select substr('abcdefg',2,3) from dual; --bcd
--获取字符串长度 24 28
select length('abcdefg') from dual;
--去除字符左右两边的空格
select trim(' hello ') from dual;
--替换字符串
Select replace('hello','l','a') from dual;
--日期函数
--查询今天的日期
select sysdate from dual;
--查询3个月后的今天的日期
select add_months(sysdate,3) from dual;
--查询3天后的日期
select sysdate + 3 from dual;
--查询员工入职的天数
select sysdate - hiredate from emp;
select ceil(sysdate - hiredate) from emp;
--查询员工入职的周数
select (sysdate - hiredate)/7 from emp;
--查询员工入职的月数
select months_between(sysdate,hiredate) from emp;
--查询员工入职的年份
select months_between(sysdate,hiredate)/12 from emp;
--转换函数 数值转字符 字符转数值 日期
--字符转数值 to_number(str) 鸡肋
select 100+'10' from dual; --110 默认已经帮我们转换
select 100 + to_number('10') from dual; --110
--数值转字符
select to_char(sal,'$9,999.99') from emp;
select to_char(sal,'L9,999.99') from emp;
/*
to_char(1210.73, '9999.9') 返回 '1210.7'
to_char(1210.73, '9,999.99') 返回 '1,210.73'
to_char(1210.73, '$9,999.00') 返回 '$1,210.73'
to_char(21, '000099') 返回 '000021'
to_char(852,'xxxx') 返回' 354'
--日期转字符 to_char()
select to_char(sysdate,'yyyy-mm-dd hh:mi:ss') from dual;
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
--只想要年
select to_char(sysdate,'yyyy') from dual; --201
--只想要日
select to_char(sysdate,'d') from dual; --2 代表一个星期中第几天
select to_char(sysdate,'dd') from dual; --10 代表一个月中的第几天
select to_char(sysdate,'ddd') from dual; --100 代表一年中的第几天
select to_char(sysdate,'day') from dual; --monday
select to_char(sysdate,'dy') from dual; --mon 星期的简写
--字符转日期
select to_date('2017-04-10','yyyy-mm-dd') from dual;
--查询1981年 -- 1985年入职的员工信息
select * from emp where hiredate between to_date('1981','yyyy') and to_date('1985','yyyy');
/*
通用函数:
nvl(参数1,参数2) 如果参数1 = null 就返回参数2
nvl2(参数1,参数2,参数3) 如果参数1 = null ,就返回参数3, 否则返回参数2
nullif(参数1,参数2) 如果参数1 = 参数2 那么就返回 null , 否则返回参数1
coalesce: 返回第一个不为null的值
*/
select nvl2(null,5,6) from dual; --6;
select nvl2(1,5,6) from dual; --5;
select nullif(5,6) from dual; --5
select nullif(6,6) from dual; --null
select coalesce(null,null,3,5,6) from dual; --3
select ceil(-12.5) from dual; --12
select floor(12.5) from dual; --12
select ' hello ' from dual;
select * from emp;
七 多表查询,子查询 集合运算
select * from bonus;
select * from salgrade
多表查询:
笛卡尔积: 实际上是两张表的乘积,但是在实际开发中没有太大意
格式: select * from 表1,表2
select * from emp;
select * from dept
select * from emp, dept;
select * from emp e1, dept d1 where e1.deptno = d1.deptno;
内联接:
隐式内联接:
等值内联接: where e1.deptno = d1.deptno;
不等值内联接: where e1.deptno <> d1.deptno;
自联接: 自己连接自己
显示内联接:
select * from 表1 inner join 表2 on 连接条件
inner 关键字可以省略
select * from emp e1, dept d1 where e1.deptno <> d1.deptno
--查询员工编号,员工姓名,经理的编号,经理的姓名
select e1.empno,e1.ename,e1.mgr,m1.ename
from emp e1, emp m1 where e1.mgr= m1.empno;
--查询员工编号,员工姓名,员工的部门名称,经理的编号,经理的姓名
select e1.empno,e1.ename,d1.dname,e1.mgr,m1.ename
from emp e1, emp m1,dept d1 where e1.mgr= m1.empno and e1.deptno = d1.deptno;
--查询员工编号,员工姓名,员工的部门名称,经理的编号,经理的姓名,经理的部门名称
select e1.empno,e1.ename,d1.dname,e1.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 e1.empno,e1.ename,d1.dname,s1.grade,e1.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
--查询员工编号,员工姓名,员工的部门名称,员工的工资等级,经理的编号,经理的姓名,经理的部门名称,经理的工资等级
select e1.empno,e1.ename,d1.dname,s1.grade,e1.mgr,m1.ename,d2.dname,s2.grade
from emp e1, emp m1,dept d1,dept d2,salgrade s1,salgrade s2
where
e1.mgr= m1.empno
and e1.deptno = d1.deptno
and m1.deptno = d2.deptno
and e1.sal between s1.losal and s1.hisal
and m1.sal between s2.losal and s2.hisal
--查询员工编号,员工姓名,员工的部门名称,员工的工资等级,经理的编号,经理的姓名,经理的部门名称,经理的工资等级
--将工资等级 1,2,3,4 显示成 中文的 一级 二级 三级...
select e1.empno,
e1.ename,
d1.dname,
case s1.grade
when 1 then '一级'
when 2 then '二级'
when 3 then '三级'
when 4 then '四级'
else
'五级'
end "等级",
e1.mgr,
m1.ename,
d2.dname,
decode(s2.grade,1,'一级',2,'二级',3,'三级',4,'四级','五级') "等级"
from emp e1, emp m1,dept d1,dept d2,salgrade s1,salgrade s2
where
e1.mgr= m1.empno
and e1.deptno = d1.deptno
and m1.deptno = d2.deptno
and e1.sal between s1.losal and s1.hisal
and m1.sal between s2.losal and s2.hisal
--查询员工姓名和员工部门所处的位置
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
外连接: (标准,通用写法)
左外连接: left outer join 左表中所有的记录,如果右表没有对应记录,就显示空
右外连接: right outer join 右表中的所有记录,如果左表没有对应记录,就显示空
outer 关键字可以省略
Oracle中的外连接: (+) 实际上是如果没有对应的记录就加上空值
select * from emp e1,dept d1 where e1.deptno = d1.deptno(+);
select * from emp e1 left outer join dept d1 on e1.deptno = d1.deptno;
insert into emp(empno,ename) values(9527,'HUAAN');
select * from emp e1,dept d1 where e1.deptno = d1.deptno(+);
select * from emp e1 right outer join dept d1 on e1.deptno = d1.deptno;
select * from emp e1,dept d1 where e1.deptno(+) = d1.deptno;
子查询: 查询语句中嵌套查询语句; 用来解决复杂的查询语句
查询最高工资的员工信息
单行子查询: > >= = < <= <> !
多行子查询: in not in >any >all exists not exists
查询领导信息
--查询最高工资的员工信息
--1.查询出最高工资 --5000
select max(sal) from emp;
--2. 工资等于最高工资
select * from emp where sal = (select max(sal) from emp);
--查询出比雇员7654的工资高,同时和7788从事相同工作的员工信息
--1.雇员7654的工资 1250
select sal from emp where empno = 7654;
--2.7788从事的工作 ANALYST
select job from emp where empno = 7788;
--3.两个条件合并
select * from emp where sal > 1250 and job = 'ANALYST';
select * from emp where sal > (select sal from emp where empno = 7654) and job = (select job from emp where empno = 7788);
--查询每个部门最低工资的员工信息和他所在的部门信息
--1.查询每个部门的最低工资,分组统计
select deptno,min(sal) minsal from emp group by deptno;
--2.员工工资等于他所处部门的最低工资
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
exists
通常情况下, 数据库中不要出现null 最好的做法加上 is Not null
null值并不代表不占空间, char(100) null 100个字符
--查询领导信息
--1.查询所有经理的编号
select mgr from emp;
select distinct mgr from emp;
--2.结果
select * from emp where empno in (select mgr from emp);
--查询不是领导的信息
select * from emp where empno not in (select mgr from emp);
select * from emp where empno <>all(select mgr from emp);
--正确的写法
select * from emp where empno not in (select mgr from emp where mgr is not null);
--查询出比10号部门任意一个员工薪资高的员工信息 10 20 30
select * from emp where sal >any (select sal from emp where deptno = 10)
--查询出比20号部门所有员工薪资高的员工信息 10 20 30
--1.20号最高工资 5000
select max(sal) from emp where deptno =20;
--2.员工信息
select * from emp where sal > (select max(sal) from emp where deptno =20);
-----使用多行子查询完成上面这题
---------20号部门所有员工薪资 (800 2975 ...)
select sal from emp where deptno = 20;
---------大于集合所有的
select * from emp where sal >all(select sal from emp where deptno = 20);
exists(查询语句) : 存在的意思,判断一张表里面的记录是否存在与另外一张表中
当作布尔值来处理:
当查询语句有结果的时候, 就是返回true
否则返回的是false
数据量比较大的时候是非常高效的
select * from emp where exists(select * from emp where deptno = 1234567);
select * from emp where 3=4;
select * from emp where exists(select * from emp where deptno = 20);
--查询有员工的部门的信息
select * from dept d1 where exists(select * from emp e1 where e1.deptno = d1.deptno );
--找到员工表中工资最高的前三名(降序排序)
select * from emp order by sal desc;
rownum : 伪列, 系统自动生成的一列, 用来表示行号
rownum是Oracle中特有的用来表示行号的, 默认值/起始值是 1 ,在每查询出结果之后,再添加1。
rownum最好不做大于号判断,可以做小于号判断
SQL执行顺序
from .. where ..group by..having .. select..rownum..order by
Select rownum,e1.* from emp e1;
--查询rownum大于2的所有记录 ,
select rownum,e1.* from emp e1 where rownum > 2; --没有任何记录
--查询rownum大于等于1的所有记录
select rownum,e1.* from emp e1 where rownum >=1;
--查询rownum < 6 的所有记录
select rownum,e1.* from emp e1 where rownum < 6;
--rownum 排序
Select rownum,e1.* from emp e1 order by sal;
--找到员工表中工资最高的前三名
select e1.* from emp e1 order by sal desc;
--将上面的结果当作一张表处理,再查询
select rownum, t1.* from (select e1.* from emp e1 order by sal desc) t1;
--只要显示前三条记录
select rownum, t1.* from (select e1.* from emp e1 order by sal desc) t1 where rownum < 4;
--找到员工表中薪水大于本部门平均薪水的员工
--1.分组统计部门平均薪水
select deptno,avg(sal) avgsal from emp group by deptno;
--2.员工工资 > 本部门平均工资
select * from emp e1,(select deptno,avg(sal) avgsal from emp group by deptno) t1
where e1.deptno = t1.deptno and e1.sal > t1.avgsal;
关联子查询 , 非关联子查询
select * from emp e where 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') yy,count(1) cc from emp group by to_char(hiredate,'yyyy');
select yy
from
(select to_char(hiredate,'yyyy') yy,count(1) cc from emp group by to_char(hiredate,'yyyy')) tt;
select case yy when '1987' then cc end
from
(select to_char(hiredate,'yyyy') yy,count(1) cc from emp group by to_char(hiredate,'yyyy')) tt;
select 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')) tt;
--去除行记录中的空值
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')) tt;
--统计员工的总数
select sum(cc) "TOTAL"
from
(select to_char(hiredate,'yyyy') yy,count(1) cc from emp group by to_char(hiredate,'yyyy')) tt;
--将1987 和TOTAL 合并在一起
select
sum(cc) "TOTAL",
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')) tt;
--显示所有年份的结果
select
sum(cc) "TOTAL",
sum(case yy when '1980' then cc end) "1980",
sum(case yy when '1981' then cc end) "1981",
sum(case yy when '1982' then cc end) "1982",
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')) tt;
rowid : 伪列 每行记录所存放的真实物理地址
rownum : 行号 , 每查询出记录之后,就会添加一个行号
select rowid,e.* from emp e;
--去除表中重复记录
create table p(
name varchar2(10)
);
insert into p values('黄伟福');
insert into p values('赵洪');
insert into p values('杨华');
delete from p where
select rowid,p.* from p;
select distinct * from p;
delete from p p1 where rowid > (select min(rowid) from p p2 where p1.name = p2.name);
rownum : 分页查询
在oracle中只能使用子查询来做分页查询
--查询第6 - 第10 记录
select rownum, emp.* from emp;
select rownum hanghao, emp.* from emp;
select * from (select rownum hanghao, emp.* from emp) tt where tt.hanghao between 6 and 10;
集合运算:
并集: 将两个查询结果进行合并
交集
差集
所有的查询结果可能不是来自同一张表,
emp 2000年
2017年 手机 详细信息 emp2017
--工资大于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 union all
union : 去除重复的,并且排序
union all : 不会去除重复的
select * from emp where sal > 1500
union
select * from emp where deptno = 20;
select * from emp where sal > 1500
union all
select * from emp where deptno = 20;
交集运算: intersect
--工资大于1500,并且20号部门下的员工
select * from emp where sal > 1500;
select * from emp where deptno = 20;
select * from emp where sal > 1500
intersect
select * from emp where deptno = 20;
差集运算: 两个结果相减
--1981年入职员工(不包括总裁和经理)
--1981年入职员工
select * from emp where to_char(hiredate,'yyyy')='1981';
--总裁和经理
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';
集合运算中的注意事项:
1.列的类型要一致
2.按照顺序写
3.列的数量要一致,如果不足,用空值填充
select ename,sal from emp where sal > 1500
union
select ename,sal from emp where deptno = 20;
--列的类型不匹配
select ename,sal from emp where sal > 1500
union
select sal,ename from emp where deptno = 20;
--列的数量不匹配
select ename,sal,deptno from emp where sal > 1500
union
select ename,sal from emp where deptno = 20;
select ename,sal,deptno from emp where sal > 1500
union
select ename,sal,null from emp where deptno = 20;
select ename,sal,deptno from emp where sal > 1500
union
select ename,sal,66 from emp where deptno = 20;
select * from emp;
select * from dept;