一:安装oracle
Linux系统要求:
内存,CPU,足够的大。
物理内存:必须高于1G,对于VMware虚拟机不少于1.5G。
一:基础内容
1:SYS:SYS用户是Oracle中的一个超级用户。
system:system用户是Oracle中默认数据库管理员。
scott:scott是Oracle数据库中一个示范用户。
1:设置每行显示的数据长度:SET LINESIZE 300;
设置每次显示的行数:SET PAGESIZE 30;
查看当前用户:
show user;
切换用户:
CONN system/manager 链接用户和密码
sqlplus /nolog
CONN sys/change_on_install as sysdba
拷贝本机
copy e:\date e:\hello.sql
DML(数据操作语言):数据的更新与操作(select、from、insert、group by、delete)
DDL(数据定义语言):数据库对象的定义语言、如:数据表、约束、索引、同义词
DLC(数据库控制语言):数据库的权限控制
--------------------------------------------------------------------------------------------------
1、启动监听
[[email protected] ~]$ : lsnrctl
参数:
start:启动监听进程
stop:停止监听进程
status:查看监听进程状态
reload:重新加载监听进程
set:设置相应参数
help:显示帮助信息。
version:显示当前监听进程版本
change_password:修改口令
2、关闭监听
[[email protected] ~]$ : lsnrctl stop
总结:先启动监听、后启动数据库。
select语句:
select * from scott.dept; /查看scott.dept表中的全局信息。
describe scott.emp; /查看scott.dept表详细信息。
select ename from scott.dept; /查看scott.dept表已dname显示出列。
select enmae,sal from scott.emp; /查看scott.emp表中所有人的姓名和工资。
select ename,sal*12 “一年工资” from scott.emp; /查看scott.emp表中所有人的姓名和工资并乘12,并且加上名称。
select deptno from scott.emp; /显示部门的编号
select DISTINCT deptno from scott.emp;/显示部门的编号并且不重复。
select ename,job from scott.emp; /显示scott.emp表中所有人名字和工作类型。
select ename || ‘ ‘ ||job from scott.emp; /查看scott.emp表,结果是:SMITH CLARK 名字和工作在一行显示,并且名字也有变化。
select ename || ‘工资’ || sal from scott.tmp;/查看scott.tmp表中的姓名-工资-金额#工资是夹在中间的别名。
select ‘编号:’ || empno || ‘,姓名: ’ || ename form scott.emp; /结果:编号:7369,姓名:SMITH
select ename || ‘工资’ || sal || ‘.‘ from scott.tmp;/查看scott.tmp表中的姓名-工资-金额。#工资是夹在中间的别名。
sql 限定查询语句条件:
阿拉伯数据和字母的区别:
阿拉伯数字带引号和不带引号都一样,阿拉伯数字针对于工资,而字母必须加引号,引号多对于人员名称等信息,而且必须和表中的一致,表中是大写必须填写大写。
1:确定数据的来源
2:筛选数据行
3:选出所需要的数据列
1:关系运算:>、=、<、>=、<=、!=或者<>;
范围运算:BETWEEN....AND;
空格判断:IS NULL ,IS NOT NULL。
IN 判断:IN、NOT IN 、exists()(复杂查询);
模糊查询:LIKE、NOT LIKE。
逻辑运算:AND与、OR或、NOT非
与操作表示的所有的判断条件满足时返回真(true);
或操作表示若干个判断条件只要有一个满足就返回真(true)。
s
select * from scott.emp where deptno=10; /显示scott.emp表中部门是10的人员信息;
select * from scott.emp where deptno=‘10’; /显示scott.emp表中部门是10的人员信息;
select * from scott.emp where ename=‘ALLEN’; /显示scitt.emp表中名字是ALLEN的列出信息;
select 5+4*7 “结果” from dual; /计算5+4*7的结果,dual相当于空表。也可以理解为回收站。
select sysdata from dual; /显示日期。格式:号-月-年
select * from scott.emp where hiredate > ‘01-JAN-87‘; /查看scott.tmp表中大于一号一月1987年的入职日期;
select * from scott.emp where sal <= 1000; /查看scott.emp表中工资小于等于1000的工资。
select * from scott.emp where sal >=2500 and sal <= 3500; /查看scott.emp表中公司大于2500并小于3500工资的列出。
select * from scott.emp where sal between 2500 and 3500; /查看scott.emp表中公司大于2500并小于3500工资的列出。
select * from scott.emp where sal = 800 or sal = 950; /查看工资等于绝对金额,其他的则不显示。
select * from scott.emp where sal in (800,950); /查看工资等于绝对金额,其他的则不显示。
select * from scott.emp where sal != 800 and sal != 950; /显示金额不等于800和950的。则其他的显示。
select * from scott.emp where job<>‘CLERK’ and sal<3000; /查询scott.emp表,不查找CLERK的信息,并且公司不小于3000;
select * from scott.emp where sal not in (800,950); /显示金额不等于800和950的。则其他的显示。
select * from scott.emp where ename = ‘ALLEN‘; /显示scott.emp表中ALLEN用户的全部信息。
like 可以实现数据的模糊查询操作,如果想使用like则不行使用如下两个符号:
_:匹配任意的一位符号;
%;匹配任意的符号(包含匹配0位、1位、多位)
select * from scott.emp where ename = ‘ALLEN‘; /查找ALLEN的信息
select * from scott.emp where ename like ‘_A%‘; /_表示站一位字符,A表示带A字母的、%表示其他。
select * from scott.emp where ename not like ‘A%‘; /A表示带A字母开头的英文名称不会显示。
select * from scott.emp where deptno like ‘10’; /查询scott.emp表中查询编号10
select * from scott.emp where comm is not null; /查看scott.emp表中COMM选项中不是空值的显示出来。
select * from scott.emp order by sal asc; /查看scott.emp表中的工资,顺序是升序,从少到多。
select * from scott.emp order by sal desc; /查看scott.emp表中的工资,顺序是降序,从多到少。
select * from scott.emp order by deptno asc, sal desc; /查看scitt.emp表中部门为升序,工资为降序。
select * from scott.emp order by 8 asc, 6 desc; /查看scitt.emp表中部门为升序,工资为降序。这种方式用的很少。
select count(*) from scott.emp /统计表中有多少行
----------------------------------------------------------------------------------------------------------------------
oracle变量;
&a = 临时变量
&&a = 永久变量
删除永久变量方法:define abc = sal;?????????????????????
select * from scott.emp; /查看一个表的全局信息。
select empno, ename, hiredate, deptno from scott.emp where ename = ‘&bl01‘; /查看ename中的一个名称,则显示张三的empno, ename, hiredate, deptno内容。
select empno, ename, deptno, sal from scott.emp where sal > &bl01 order by &bl02 asc; /第一个环境变量输入金额,第二个输入工资则排序。
select empno, ename, deptno, &&abc from scott.emp order by &abcd; /首先输入第一个变量的内容,可以是 empno, ename, deptno,然后调用,输入1、2、3。
select &abc from scott.emp; /调用表中个的关键字,如empno, ename, deptno, sal。
define abc = sal; /替换变量,针对永久变量‘&&‘
select 3+5 "jieguo" from dual; /简单的计算,dual相当于空表。
select sysdate from dual; /显示系统时间
select ‘aa‘ || ‘bb‘ from dual; /结果是aabb。
字符串函数:
select initcap(‘guodongdong‘) from dual; /返回字符串并将字符串的第一个字母变为大写;
select initcap(ename) from scott.emp; /针对scott.emp表中的ename开头全部大写。
select lower(ename) from scott.emp; /针对scott.emp表中的ename名字中全部小写。
select upper(ename) from scott.emp; /针对scott.emp表中的ename名字全部大写
select length(ename) from scott.emp; /查询scott.emp表中的ename名字所占的单词个数。
select ename,substr(ename,length(ename)-2) from scott.emp /查询Scott.emp表中的ename名字最后的三个英文名称。
或者 select ename,substr(ename,-3) from scott.emp;
select concat(‘guo‘,‘dongdong‘) from dual; /CONCAT只能连接两个字符串,没有|| 强大。
select concat(ename,sal) from scott.emp; /针对scott.emp表中的名字个工资做一个连接。
select substr(‘guodongdong‘,1,5) from dual; /查询guodongdong,1-5的单词列出。
select lpad(‘guodongdong‘,15,‘*‘) from dual; /显示guodongdong,15表示15为,不够15为则在前方补*。
select rpad(‘guodongdong‘,15,‘*‘) from dual; /显示guodongdong,15表示15为,不够15为则在后方补*。
select replace(‘guodongdong‘,‘d‘,‘j‘) from dual; /修改guodongdong,d单词全部替换为j,则是guojongjong
select trim(‘k‘ from ‘gkgguodonkkgdonggg‘) from dual; /只要gkgguodonkkgdonggg去除指定字符的前后空格。
数值函数:
三个主要函数:ROUND,trunc,mod
1: SELECT
round(78915.67823823), 78916,小数点之后的内容直接进行四舍五入
round(78915.67823823,2), 78915.68,保留两位小数
round(78915.67823823,-2), 78900,把不足5的数据取消了
round(78985.67823823,-2), 79000,如果超过了5则进行进位
round(-15.65) ; -16
from dual;
2:截取小数,所有的小数都不进位
SELECT
trunc(78915.67823823), 78916,小数点之后的内容直接进行四舍五入
trunc(78915.67823823,2), 78915.68,保留两位小数
trunc(78915.67823823,-2), 78900,把不足5的数据取消了
trunc(78985.67823823,-2), 79000,如果超过了5则进行进位
trunc(-15.65) ; -16
from dual;
3:求模(求余数)
select mod(10,3) from dual; 得1
-----------------------------------------------------------------------------------------------------------------------------
日期函数:(oracle 自己特色)
select ename,hiredate,sysdate from scott.emp ; 可以查询出员工入职到现在的日期
select sysdate,systimestamp dual;
实际上对于日期提供以下三种计算模式:
日期+数字=日期(若干天之后的日期)
select sysdate +10 from dual;
日期-数字=日期(若干天之前的日期)
select sysdate -10 from dual;
日期-日期=数字(两个日期期间的天数)
计算每一位雇员到今天为止的雇佣天数。
select ename,hiredate, sysdate-hiredate form scott.emp
计算两个日期见所经历的月数总和。
语法:数字 MONTHS_BETWEEN(日期1,日期2)
MONTHS_BETWEEN函数返回两个日期之间的月份数。
1:范例: 计算每一位员工到今天为止雇佣总月数。
select ename,hiredate,
trunc(months_between(sysdate,hiredate)/12) years from scott.emp
2:增加若干月之后的日期;
范例:测试ADD_MONTHS函数
select add_months(sysdate,4) from dual;
3:计算还要差1年满34年的雇佣日期的全部雇佣。
select * from scott.emp
where trunc(months_between(sysdate,hiredate)/12)=34 ; ?????????????????????????
4:计算指定日期所在月的最后一天
select last_day(sysdate) from dual;
5:查询出所有雇佣所在月的倒数第二天被雇佣的雇员信息
每个雇员的雇佣日期是不一样的,所有每一个雇佣日期所在月的倒数第二天也不一样。
select ename,hiredate,last_day(hiredate),last_day(hiredate)-2 from scott.emp;
6:计算下一个周二
select next_day(sysdate,‘星期二’) from dual;
7:计算scott.emp表中雇佣的员工到目前为止的雇佣年份:
select empno,ename,hiredate, trunc(months_between(sysdate,hiredate)/12) year from scott.emp
8:综合分析:要求查询出雇员的编号、姓名、雇佣日期,以及每一位雇员到今天为止被雇佣的年数,月数天数。
假设下载的日期是:2016-03-08.
select empno,ename,hiredate,
trunc(months_between(sysdate,hiredate)/12) gear,
trunc(mod(months_between(sysdate,hiredate,)/12)) months,
trunc(sysdate-add_months(hiredate,months_between(sysdate,hiredate))) day
from scott.emp;
转换函数:
三种:to_char、to_date、to_number。
yyyy-mm-dd-hh24-mi-ss
1: 格式化日期:
select to_char(sysdate,‘yyyy-mm-dd’) from dual;
2: 查询出所有在2月雇佣的日期
select * from scott.emp where to_char(hiredate,‘mm‘)=‘02‘;
3: 转换数字
select to_char(12345,‘L000,000,000.99999‘) from dual;
转日期函数:
1:实现字符串转换为日期
select to_date (‘1998-09-19’,‘yyyy-mm-dd’) from dual;
转数字函数:
可以将字符串(由数字所组成)变为数字,语法:数字 to_number(字符串)
范例:
select to_number (‘1’) + to_number(‘2’) from dual;
select ‘1’ + ‘2’ from dual;
sekect sysdate + 3/24 from dual;
select to_char(sysdate,‘yyyy-mm-dd:fmhh24:mi:ss‘) from dual; /显示时间年-月-日-小时-分钟-秒,加fm则不显示0。
select to_char(hiredate, ‘ss:yyyy+mm+dd‘) from scott.emp; ??????????????????????????
select to_char(hiredate, ‘ss:yyyy+mm+dd‘) from scott.emp; alter session set nls_date_format=‘yyyy-mm-dd:hh24:mi:ss‘ ????
select to_char(12345,‘L000,000,000.99999‘) from dual; ????????????????
select ename, hiredate from scott.emp where hiredate < ‘2010-1-1‘; /列出scott.emp表中入职人员和时间的日期小于2010-1-1。
select to_number(‘$124.00‘,‘$999.99‘) from dual; /主要是将字符串转换为数值型的格式,与TO_CHAR()函数的作用正好相反。
select nvl(comm,4) from scott.emp; /通过查询获得某个字段的合计值,如果这个值位null将给出一个预设的默认值
select nvl2(3,1,2) from dual; ??????????????????
NVL2(expr1,expr2,expr3)
如果参数表达式expr1值为NULL,则NVL2()函数返回参数表达式expr3的值;如果参数表达式expr1值不为NULL,则NVL2()函数返回参数表达式expr2的值。
select nullif(4,5) from dual; /如果表达式1和表达式2相等则返回空值,如果表达式1和表达式2不相等则返回表达式1的结果。
select coalesce(1,null,null,null,4,5,null) from dual; /语法为COALESCE(表达式1,表达式2,...,表达式n),
n>=2,此表达式的功能为返回第一个不为空的表达式,如果都为空则返回空值。
---------------------------------------------------------------------------------------------------------------------------------
select last_name,job_id, salary, /查找名字、工作id、工资。
case job_id when ‘SH_CLERK‘ then 1.2*salary /案列 job_id 什么时候 ‘SH_CLERK’ 然后 工资乘以1.2
when ‘AD_ASST‘ then 1.5*salary /什么时候 ‘AD_SAAT’ 然后 工资乘以1.5
when ‘MK_MAN‘ then 2*salary /什么时候 ‘MK_MAN’ 然后 工资乘以1.5
else salary end "chuli" /其他工资不变,结束,别名处理。
from hr.employees; /选择表名
------------------------------------
疑问:
1:select ename, hiredate from scott.emp where hiredate > to_date(‘17-DEC-80‘); /加入日期是2015-12-26格式,使用这种格式查找不出来吗?
2:select nvl2(3,1,2) from dual;
3:select last_name,salary,
decode( trunc(salary/2000),0,‘xiaoyu liangqian‘,
1,‘yi bei‘,
2,‘er bei‘,
‘buguanzhu‘) "chuli"
from hr.employees;
IN操作符
IN指的是根据一个指定的范围进行数据查询
1:IN函数有助于减少OR条件的复合使用。
2:关于操作符IN和=的比较。
范例:查询出雇员编号是7369、7566、7788、9999的雇员信息
利用关系运算符进行操作
select * from scott.emp where empno=7369 or empno=7566 or empno=7788 or empno=9999;
select * from scott.emp where empno IN (7369,7566,7788,9999);
select * from scott.emp where NOT IN (7369,7566,7788,9999); 相反
复习:
找出佣金高于薪金的百分之60的员工。
select * from scott.emp where comm>sal*0.6;
----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
通用函数:(oracle自己特色)
1:处理Null;
Oracle中函数中除了字符函数、日期函数、数学函数、以及转换函数等等,还有一些函数是通用函数,比如:NVL、NVL2,、NULLIF、COALESCE。
解释 NVL函数
NVL(expr1,expr2)
如果expr1和expr2的数据类型一致,则:
如果expr1为空(null),那么显示expr2,
如果expr1的值不为空,则显示expr1 。
范例:查找编号、姓名、工资、工资、佣金、如果佣金为空则显示0,工资和佣金在乘以12.
select empno,ename,job,sal,comm,NVL(comm,0),(sal+comm)*12 income from scott.emp;
select empno,ename,job,sal,comm,nvl(comm,0),(sal+nvl(comm,0))*12 income from scott.emp;
2:多数值判断;
含义解释: decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值)
select empno,ename,job,DECODE(job,‘CLERK’,‘办事员’,‘SALESMAN’,‘销售’) from scott.emp;
select empno,ename,job,DECODE(job,‘CLERK’,‘办事员’,‘SALESMAN’,‘销售’,‘暂无此信息’) from scott.emp;
-----------------------------------------------------------------------------------------------------------------------------------
3.1:认识多表查询
实际上所谓的多表查询指的就是从多张数据表中取出数据并且显示的一种操作。
select * from scott.emp,dept.emp 笛卡尔积存在的原因
实际:
SELECT * FROM scott.emp e, scott.dept d WHERE e.deptno=d.deptno;
-----------------------------------------------------------------------------------------------------------------------------------
3.2:查询分析
范例1:查询出每个雇员的编号,姓名、职位、基本工资、部门名称、部门位置。
·确定要使用的数据表:
-:emp表:编号,姓名、职位、基本工资、
-:detp表:部门名称、部门位置。
·确定已知的关联字段:
-:雇员与部门:emp.deptno=dept.deptno
第一步:查询出每个雇员的编号,姓名、职位、基本工资。
select e.empno,e.ename,e.job,e,sal from emp e;
第二步:查询出每个雇员对应的部门信息;需要引入dept表(引入表的时候一定考虑有关联),deptno字段关联,所以利用where子句消除笛卡尔积。
select e.empno,e.ename,e.job,e.sal,d.dname,d.loc
from scott.emp e, scott.dept d
where e.deptno=d.deptno;
范例2:查询出每个雇员的编号,姓名、职位、基本工资、工资等级。
select e.empno,e.ename,e.job,e.sal,s.grade
from scott.emp e,scott.salgrade s
where e.sal BETWEEN s.losal and s.hisal;
范例3:查询出每个雇员的编号,姓名、职位、基本工资、部门名称、工资等级。
确定所需要的数据表:
-:emp表:编号,姓名、职位、基本工资、
-:detp表:部门名称、
-:salgrade表:工资等级
确定已知的关联字段:
-:雇员与部门:emp.deptno-dept.deptno
-:雇员与工资等级;emp.sal BETWEEN salgrade.losal and salgrade.hisal
第一步:select e.empno,e.ename,e.job,e.sal
from emp e;
第二步:加入部门名称、增加一张表就增加一条消除笛卡尔积。
select e.empno,e.ename,e.job,e.sal,d.dname
from emp e,dept d
where e.deptno=d.deptno;
第三步:加入工资等级信息,与原始的
select e.empno,e.ename,e.job,e.sal,d.dname,s.grade
from emp e,dept d,salgrade s
where e.deptno=d.deptno and e.sal between s.losal and s.hisal;
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
表的连接:
内连接:
笛卡尔积就属于内连接。只有满足条件的情况下才会显示。
外连接:
分为三种:左外连接,右外连接、全外连接
为了更好的观察到连接的区别,现在已经在scott.dept表中提供了一个没有雇员的部门(40部门),同时现在在scott.emp表中增加一个没有部门的雇员。
insert into scott.emp (empno,ename,deptno) values(899,‘hello’,null);
可查看 select * from scott.emp;
观察一:内连接实现效果
select e.empno,e.ename,d.dname,d.deptno
from scott.emp e, scott.dept d
where e.deptno=d.deptno;
观察二:使用左外连接;希望所有的雇员信息都显示出来,即便没有部门
select e.empno,e.ename,d.dname,d.deptno
from scott.emp e, scott.dept d
where e.deptno=d.deptno(+);
观察三:使用右外连接,将所有的部门信息显示出来;
select e.empno,e.ename,d.dname,d.deptno
from scott.emp e, scott.dept d
where e.deptno(+)=d.deptno;
内连接指的就是满足关联条件的数据出现,不满足的不出现,外连接就是指定一张数据表中的全部内容都显示,但是没有对应的其他表数据,内容为null。
在oracle里面使用了‘(+)‘,来控制连接方式
·:左外连接:关联字段1=关联字段2(+);
·:右外连接:关联字段1(+)=关联字段2;
一般使用内连接,当你发现数据不全的时候可以考虑使用外连接;
范例:查询每个雇员的编号、姓名、职位、领导姓名、领导职位; 自身关联
确定所需要的数据表:
scott.emp表:(雇员信息):编号、姓名、职位
scott.emp表:(领导信息):领导姓名、领导职位
确定已知的关联字段
雇员和领导:scott.mgr=memp.empno
第一步:查询scott.emp表中的编号、姓名、职位。
select e.empno,e.ename,e.job
from scott.emp e;
第二步:加入领导信息,需要引入自身关联,标出笛卡尔积
select e.empno,e.ename,e.job,m.ename,m.job
from scott.emp e,scott.emp m
where e.mgr=m.empno;
第三部:发现emp表雇员信息,数据不完整。如何想全部显示则使用外连接
select e.empno,e.ename,e.job,m.ename,m.job
from scott.emp e,scott.emp m
where e.mgr=m.empnp(+);
-----------------------------------------------------------------------------------------------------------------------------------
SQL:1999语法定义
-----------------------------------------------------------------------------------------------------------------------------------
数据集合操作
UNION (无重并集):当执行UNION 时,自动去掉结果集中的重复行,并以第一列的结果进行升序排序。
范例:UNION 操作
select * from scott.emp
UNION
select * from scott.emp where deptno=10;
此时的查询结果已经连接在一起了,但是UNION的处理过程是属于取消重复元素;
范例2:UNION ALL 操作
UNION ALL (有重并集):不去掉重复行,并且不对结果集进行排序。
select * from scott.emp
UNION ALL
select * from scott.emp where deptno=10;
范例:验证INTERSECT操作
INTERSECT(交集):取两个结果集的交集,并且以第一列的结果进行升序排列。
select * from scott.emp
INTERSECT
select * from scott.emp where deptno=10;
范例:验证差集
MINUS (差集):只显示在第一个集合中存在,在第二个集合中不存在的数据。并且以第一列的结果进行升序排序。
select * from scott.emp
MINUS
select * from scott.emp where deptno=10;
7782 7839 7934
-----------------------------------------------------------------------------------------------------------------------------------
第五章:分组统计查询:
5-1:统计函数:(分组函数)
常用的函数:
·:统计个数:COUNT(),根据表中的实际数据量返回结果;
·:求和:SUM(),是针对于数字的统计,求和
·:平均值:AVG(),各种数据类型都支持
·:最大值:MAX(),各种数据类型都支持
·:最小值:MIN(),求出最小值
范例:验证各个函数:
select count(*) 人数,AVG(sal)员工平均工资,SUM(sal)每月总支出,
max(sal) 最高工资,min(sal)最低工资
from scott.emp;
范例:统计出公司的平均雇用年限
select avg(months_between(sysdate,hiredate)/12) from scott.emp;
范例:求出最早和最晚的雇佣日期
select max(hiredate)最晚,min(hiredate)最早 from scott.emp;
以上的几个操作函数,在表中没有数据的时候,只有CIUNT()函数会返回结果,其他都是NULL;
范例:统计bonus表
select count(*) 人数,AVG(sal)员工平均工资,SUM(sal)每月总支出,
max(sal) 最高工资,min(sal)最低工资
from bonus;
实际上针对于count()函数有三种使用形式;
·count(*):可以准确的说返回表中的全部记录数;
·count(字段):统计不为null的所有数据量;
·connt(DISTINCT 字段);消除重复之后的结果;
范例:统计查询一
select count(*),count(empno),count(comm) from scott.emp;
统计查询二:
select count (DISTINCT job) from scott.emp;
5-2:分组统计
范例:根据部门编号分组、查询出每个部门的编号、人数、平均工资。
select count(deptno) 编号,count(*),Avg(sal)
from scott.emp
group by deptno;
范例:根据职位分组,统计出每个职位的人数,最低工资与最高工资。
select job,count(*),min(sal),MAX(sal)
from scott.emp
group by job;
5-3:多表查询与分组统计
范例:查询出每个部门的名称、部门人数、平均工资。
确定要使用的数据表
dept表:部门名称
emp表:统计数据
确定已知的关联字段
雇员与部门:scott.emp.deptno=scott.dept.deptno
第一步:换个思路,查询出每个部门的名称,雇员编号(count(empno))、基本工资(AVG(sal))
select d.ename,e.empno,e.sal
from scott.emp e,scott.emp d
where e.deptno=d.deptno;
第二步:
select d.ename,count(e.empno),AVG(e.sal)
from scott.emp e,scott.emp d
where e.deptno=d.deptno
group by d.ename;
第三部:外连接
select d.dname,count(e.empno),AVG(e.sal)
from scott.emp e,scott.emp d
where e.deptno(+)=d.deptno
group by d.ename;
范例:查询每个部门的编号、名称、位置、部门人数、平均工资;
确定要使用的数据表
dept表:编号、名称、位置
emp表:统计信息
确定已知的关联字段
雇员与部门:scott.emp.deptno=scott.dept.deptno
select d.deptno,d.dname,d.loc,e.empno,e.sal
from scott.emp e, scott.dept d
where e.deptno(+)=d.deptno;
第二步:此时发现有三个列(dept表)同事发生着重复,呢么就可以进行多字段分组。
select d.deptno,d.dname,d.loc,count(e.empno),avg(e.sal)
from scott.emp e, scott.dept d
where e.deptno(+)=d.deptno
group by d.deptno,d.dname,d.loc;
5-4: HAVING子句
现在要求查询出每个职位的名称,职位的平均工资,但是要求显示的职位的平均工资高于2000。
即:按照职位先进行分组,同时统计出每个职位的平均工资
随后要求直显示哪些平均工资高于2000的职位信息
select job,avg(sal)
from scott.emp;
group by job
having avg(sal)>2000
5-5:分组案例总结
范例:显示所有非销售人员的工作名称以及从事同一工作雇员的月工资总和,并且要求满足从事同一工作雇员的月工资的合计大于5000,显示的结果按照月工资的合计升序排列;
第一步:查询所以人非销售人员的信息。
select *
from scott.emp
where job<>‘SALESMAN’;
第二步:按照职位进行分组,而后求出工资的总支出:
select job,SUM(sal)
from scott.emp
where job<>‘SALESMAN’
group by job;
第三部:分组后的数据进行再次筛选,使用HAVING语句
select job,SUM(sal)
from scott.emp
where job<>‘SALESMAN’
group by job
having sum(sal)>5000;
第四步:按照月工资的合计升序排列;使用order by
select job,SUM(sal) sum
from scoot.emp
where job<>‘SALESMAN’
group by job
having sum(sal)>5000
order by sum;
范例二:查询出所有领取佣金的雇员的人数,平均工资。
select ’领取佣金‘ info ,count(*), avg(sal)
from scott.emp
where comm is not null
nuion
select ‘不领取佣金‘ info, count(*),avg(sal)
from scott.emp
where comm is null;
---------------------------------------------------------------------------------------------------------------------
6、子查询:
6-1:子查询简介
6-2:
select * from scott.emp
where sal=(select MIN(sal) from scott.emp);
范例:查找出公司雇佣最早的雇员;
select min(hiredate) from scott.emp
以上查询会返回单行单列的数据,所有可以直接在where语句中使用.
select * from scott.emp
where hiredate=(select min(hiredate) from scott.emp);
6.1.2、子查询返回单行多列;
范例:查询出与scott工资相同,职位相同的所有雇员信息。
select * from scott.emp where (sal,job)=(select sal,job from scott.emp where ename=‘SCOTT‘);
6.1.3 子查询返回多行单列(重点)
在where字句里面提供有主要的三个运算符:IN、ANY、ALL。
1:IN操作;
IN操作指的是内容可以在指定的范围之中存在,
1.1:select sal from scott.emp where job=‘MANAGER’;
2975
2850
2450
1.2:select * from scott.emp
WHERE (sal,job)=(
select sal,job FROM scott.emp where ename=‘SCOTT‘);
多行单列就相当于给出了一个查询范围;
对于IN操作还可以使用not IN 进行;
select * from scott.emp
where sal NOT IN (select sal from scott.emp where job=‘MANAGER’;
2:ANY操作实际上有三种语法:
1:=ANY:功能上与IN完全是没有任何区别;
select * from scott.emp
where sal =ANY (select sal from scott.emp where job=‘MANAGER’;
2:>ANY:比子查询返回的最小的内容要大
select * from scott.emp
where sal >ANY (select sal from scott.emp where job=‘MANAGER’;
3:<ANY:比子查询返回的最大的值要小
select * from scott.emp
where sal <ANY (select sal from scott.emp where job=‘MANAGER’;
3:ALL操作
ALL两种操作
1:>ALL: 比子查询返回的最大值要大
select * from scott.emp
where sal >ALL (select * from scott.emp where job=‘MANAGER’;
2:<ALL: 比子查询的返回最小的值要小
select * from scott.emp
where sal <ALL (select * from scott.emp where job=‘MANAGER’;
4:EXISTS()判断
范例:观察exists()操作
select * from scott.emp
where exists(select * from scott.emp where deptno=99);
因为此时的查询没有返回任何的数据行买,所以exists()就认为数据不存在,外部查询无法查询出我内容。
范例:观察exists()操作
select * from scott.emp
where exists(select * from scott.emp where empno=7839);
范例:观察exists()操作
select * from scott.emp
where exists (select ‘hello’ from dual where 1=1);
范例:使用not exists()
select * from scott.emp
where not exists (select ‘hello’ from dual where 1=2);
6-3:使用HAVING字句查询;
范例:要求统计出高于公司平均工资的部门编号、平均工资、部门人数。
第一步:根据部门编号分组,统计出每个部门编号的平均工资、部门人数。
select deptno,count(*),avg(sal)
from scott.emp
group by deptno;
第二步:如果要想知道哪些部门的工资高于公司的平均工资,则应该scott.emp表统计查询
select avg(sal) from scott.emp;
第三步:统计函数
select deptno,count(*),avg(sal)
from scott.emp
group by deptno
having avg(sal)>(select avg(sal) from scott.emp);
6-4:select 子句使用子查询
首先需要明确的是,这样的操作意义不大,而且性能不高;
范例:查询每个雇员的编号,姓名,职位,部门名称;
select e.empno,e.ename,e.job,d.dname
from scott.emp e,soctt.emp d
where e.deptno=d.deptno;
6-5:FROM字句使用子查询(重点)
为了解释这种查询的作用,下面做一个简单的查询;
select d.deptno,d.dname,d.loc,scott