/*
一、单行子查询
格式:select <列明表> from 表名(查询select 语句)
where 列或表达式 比较运算符(SELECT 列名 FROM 表名 WHERE 条件)
-- 子查询,必须要使用小括号括起来
---
最大值函数:max()
最小值函数: min()
二、 from 子查询
from 后面的表不是一个具体的表,而是一个查询或者多层查询S果
从1开始可以是 >= 或者 between and
*/
例题:
-- 单行子查询:是指只返回一行(或者说是,一个记录)的子查询
-- 例如:查找出与‘SMITH'在同一个部门(deptno)工作的所有职工姓名以及工资
-- 1.1、找出SMITH所在的部门号
select deptno
from scott.emp
where ename = 'SMITH'; -- 20
-- 1.2、根据条件查询
select ename,sal
from scott.emp
where deptno = 20;
-- 1.3、使用子查询实现
select ename,sal
from scott.emp
where deptno = (
select deptno from scott.emp where ename = 'SMITH'
);
-- 2、查找出表中在"CHICAGO地点"工作的职工的姓名,工种、工资
-- dept - 部门表
-- deptno - 部门编号 number
-- dname - 部门名字 varcha2
-- loc - 部门送在地 varchar2
-- 2.1 在部门表dept中找到CHICAGO对应的部门号
select deptno from scott.dept where loc = 'CHICAGO';
-- 2.2 根据2.1获得的部门号查询到数据
select ename,job,sal from scott.emp where deptno = 30;
-- 2.3 子查询替换2.1和2.2
select ename,job,sal from
scott.emp
where
deptno = (select deptno from scott.dept where loc = 'CHICAGO');
-- 3、查找出工资比"SCOTT"高,并且在"NEW YORK"工作的职工的有关情况。
-- 3.1 先找出SCOTT的工资
select sal from scott.emp where ename = 'SCOTT';
-- 3.2 在部门表dept中找到new YORK 的部门号
select deptno from scott.dept where loc = 'NEW YORK'; -- 10
-- 3.3 根据条件查询
select * from scott.emp
where
sal > 3000 and deptno = 10;
-- 3.4 合并为子查询
select * from scott.emp
where
sal > (select sal from scott.emp where ename = 'SCOTT')
and
deptno = (select deptno from scott.dept where loc = 'NEW YORK')
;
-- 4、查找出工资比"SCOTT"工资高的职工的名字,工种,工资和所在的部门号,并按工资升序排序。
-- 4.1 找出scott的工资
select sal from scott.emp where ename = 'SCOTT';
-- 4.2 根据条件查询
select ename,job,sal,deptno
from scott.emp
where
sal > 3000
order by sal
;
-- 4.3 子查询替换
select ename,job,sal,deptno
from scott.emp
where
sal > (
select sal
from scott.emp
where
ename = 'SCOTT'
)
order by sal;
-- 5、查找出具有最高月工资的雇员的姓名、工种和工资。
-- 5.1 先找出最高的工资是多少 max() 最大值、min()最小值
select max(sal) from scott.emp;
-- 5.2 根据条件查询
select ename,job,sal
from scott.emp
where
sal = 5000
;
-- 5.3 子查询合并
select ename,job,sal
from scott.emp
where
sal = (
select max(sal) from scott.emp
)
-- 6、列出与SCOTT从事相同工作的雇员
select ename
from scott.emp
where job = (
select job
from scott.emp
where
ename = 'SCOTT'
)
;
-- 7、列出某些雇员的姓名和佣金,条件是他们的薪资等于部门30中任何一个雇员的薪资
select ename,sal
from scott.emp
where
sal in(
select sal from scott.emp where deptno = 30
)
and
deptno != 30
;
-- 8、列出某些雇员的姓名和佣金,条件是他们的薪资高于部门30中所有雇员的薪资
select ename,sal
from scott.emp
where
sal > (
select max(sal)
from scott.emp
where
deptno = 30
)
;
-- 9、列出薪资水平处于第四位的雇员
/*
这里涉及到一个函数:
rownum:伪列 取序号 从1开始
from子查询
*/
-- 9.1 对薪资表进行排序
select * from scott.emp order by sal desc;
-- 9.2 使用form子查询9.1sql,并且使用rownum获取行号
select e.*,rownum r
from(
select * from scott.emp
order by sal desc
) e
;
-- 9.2 合并子查询
select * from(
select e.*,rownum r
from (
select * from scott.emp
order by sal desc
) e
) where r = 4
;
-- 11、不用分组函数求出薪水的最大值
select max(sal) from scott.emp;
-- 子查询替换
select * from scott.emp
where sal = (
select max(sal) from scott.emp
)
;
-- 12、查询所有工资高于平均工资(平均工资包括所有员工)的销售人员(‘SALESMAN’)
-- avg() 获取到平均工资
-- 12.1 找出平均薪资
select avg(sal) from scott.emp;
-- 12.2 合并子查询
select * from scott.emp
where job = 'SALESMAN'
and
sal > (select avg(sal) from scott.emp)
;
-- 13、查询工资最高的3名员工信息(from子查询)
-- rownum 取序列号
-- 子查询工资降序
-- 子查询的表是降序表
select e.*,rownum r
from (
select * from scott.emp
order by sal desc
) e
where rownum < 4
/*
三、with as 语句
语法:
with
别名 as (select 语句)
别名 as (select 语句)
...
select 查询
-------
语句作用:
可以创建一个自定义别名(作为表名)的sql临时表
在后续操作,可以方便从sql中直接提取临时表进行使用
*/
-- 1、 举例:找出emp表中工资排名为6-10的记录
-- 1.1 from子查询
with a as (select * from scott.emp order by nvl(sal,0) desc),
b as (select a.*,rownum r from a)
select * from b where r between 6 and 10;
-- 2、列出薪资水平处于第四位的员工
with
a as(select * from scott.emp order by sal desc),
b as(select a.*,rownum r from a)
select * from b where r = 4
;
-- 3、查询工资最高的3名员工信息
with
a as(select * from scott.emp order by sal desc),
b as(select a.*,rownum from a where rownum < 4)
select * from b
;
-- 用bteween and
with
a as(select * from scott.emp order by sal desc),
b as(select a.*,rownum from a where rownum between 1 and 3)
select * from b
;
-- 4、查询工资高于编号为7782的员工工资,并且和7369员工从事相同工作的员工编号
select sal from scott.emp where empno = 7782;
select job from scott.emp where empno = 7369;
--合并子查询 -- 典型的单行子查询
select * from scott.emp where sal >(
select sal from scott.emp where empno = 7782
)and job = (
select job from scott.emp where empno = 7369
)
;
-- 5、显示出和员工姓名中包含W的员工相同部门的员工姓名
-- 5.1 找出部门编号
select deptno from scott.emp where ename like '%W%';
-- 5.2 用部门号去查询信息,合并子查询
select ename,deptno,empno from scott.emp
where deptno = (
select deptno from scott.emp where ename like '%W%'
)
;
-- 6、显示比工资最高的员工参加工作时间晚的员工姓名,参加工作时间
-- 6.1 找出最高工资
select max(sal) from scott.emp;
-- 6.2 通过工资找人
select hiredate from scott.emp where sal = (
select max(sal) from scott.emp
)
;
-- 6.3 通过找到的人的时间去获取到最晚的那个人
select ename,empno,hiredate,sal from scott.emp
where hiredate >(
select hiredate from scott.emp
where sal = (
select max(sal) from scott.emp
)
)
;
-- 7、查询入职日期最早的前五名员工姓名,入职日期,并显示序号
-- 7.1、时间升序
select * from scott.emp order by hiredate;
-- 7.2、通过时间升序和rownum查询
select ename,hiredate,rownum
from (
select * from scott.emp order by hiredate
)
--where rownum < 6
where rownum between 1 and 5
;
-- 8、查询工作在HICAGO并且入职日期最早的两名员工姓名,入职日期
-- 8.1 要获取到dept表的部门号
select deptno from scott.dept where loc = 'CHICAGO';
-- 8.2 从dept的部门号去查询emp表中的部门号获取到员工信息
select ename,hiredate from scott.emp
where deptno = (
select deptno from scott.dept where loc = 'CHICAGO'
)
;
-- 8.3 获取到行号,和表信息
select e.*,rownum from (
select ename,hiredate from scott.emp
where deptno = (
select deptno from scott.dept where loc = 'CHICAGO'
)
) e where rownum < 3
;
-- 8.4 使用 with as 编写
with
a as (
select * from scott.emp where deptno = (select deptno
from scott.dept where loc = 'CHICAGO') order by hiredate
)
select a.*,rownum from a where rownum between 1 and 2
;
/*
----------------四、分组/聚合函数 ------------------
聚合/统计函数:在某个结果集中计算
count(字段名或者列名):计算指定字段或列为 非空 的行数
count(*):计算表中的全部行数,包含 重复行 和 空行
avg(字段名):计算指定字段(非空)的平均值
min(字段名):计算指定字段的最小值
max(字段名):计算指定字段的最大值
sum(字段名):计算指定字段(非空)的总和
------
count()统计数据,去除重复数据关键字:distinct
count(distinct 列)
*/
-- 1、相关的函数举例
select
count(*),
count(empno),
count(comm)
from scott.emp
; -- 返回回来的是统计出来的数量num
-- 2、计算emp表中公司职工的最低工资、最高工资、平均工资、有奖金的人(奖金不为空)、总工资的综合
select
min(sal), -- 最低工资
max(sal), -- 最高工资
avg(sal), -- 平均工资
count(*), -- 表中的行总数
count(comm), -- 有奖金的人
sum(sal) -- 总工资
from scott.emp;
-- 3、计算emp表中公司职工的总人数及工种数
select count(*) zs,count(empno) zs1,count(job) from scott.emp;
-- job 去重
select count(*) zs,count(empno) zs1,count(distinct job) from scott.emp;
-- 4、计算全部销售员的年平均报酬(平均工资 * 12 + 平均奖金 *12 )
-- 4.1 找出销售员
select * from emp where job = 'SALESMAN';
-- 4.2 销售员的平均工资和平均奖金
select avg(sal),avg(comm) from scott.emp where job = 'SALESMAN';
-- 4.3 对平均的值进行计算
select avg(sal*12),avg(comm*12) from scott.emp where job = 'SALESMAN';
-- 5、统计20号部门人数和工资总和
-- 5.1 查到部门为20的员工
select * from scott.emp where deptno = 20;
-- 5.2 form查询,去统计人数和工资总和
select count(*),count(empno),sum(sal) from scott.emp where deptno = 20;
-- 6、统计每个部门人数和工资总和
select count(*),count(empno),sum(sal) from scott.emp where deptno = 20;
select count(*),count(empno),sum(sal) from scott.emp where deptno = 30;
select deptno,count(*),count(empno),sum(sal) from scott.emp group by deptno;