Oracle--组函数--分组查询--having条件--执行顺序--伪列--子查询

一、组函数 【重点】

  1. 组函数的特点: 组函数是作用于每一组数据产生一个结果。
  2. 常用的组函数:
    2.1 求平均值: avg(字段)
    2.2 求和: sum(字段)
    2.3 求最大值: max(字段)
    2.4 求最小值: min(字段)
    2.5 做统计查询的: count(…)
  3. 案例

3.1查询所有员工的平均工资

select avg(salary)
from employees;

3.2 查询所有员工的平均工资、月工资总和、最高工资、最低工资

select avg(salary),sum(salary),max(salary),min(salary)
from employees;

3.3 查询统计公司一共有多少员工
第一种方式:

 select count(*) from employees; // 返回表中非空行总数

第二种方式:

select count(employee_id) from employees;

通过指定主键进行统计, 需要注意count在进行统计时,会自动忽略掉为null值的行。 所以我们在进行全表信息总数统计查询时, 尽量使用count(主键) 或 count(*) 的方式。

3.4 查询所有有提成的员工总数

select count(commission_pct) from employees;

二、分组查询 - group by 【掌握】

  1. 语法: select 字段… from 表名 where … group by 字段 order by …;
    说明: group by 后面指定的是分组的条件字段。
  2. 案例:
    2.1 查询各个部门的平均工资
    ① 确定分组条件 : 部门编号 department_id
    ② 进行分组查询,完成结果统计运算: avg(salary)
select department_id,avg(salary)
from employees group by department_id;

2.2 查询各个部门 各个职位员工的平均工资
①确定分组条件: department_id, job_id
②进行结果统计运算查询: avg(salary)

select department_id,job_id,avg(salary)
from employees group by department_id,job_id;

2.3 查询1997年各个月份入职员工的总人数
① 按照条件筛选数据: to_char(hire_date,’yyyy’)=’1997’
② 对筛选后的数据进行分组 : 月份 > to_char(hire_date,’mm’)
③ 对分组后的数据统计查询 : count(*)

select to_char(hire_date,'mm'),count(*)
from employees
where to_char(hire_date,'yyyy')='1997'
group by to_char(hire_date,'mm') 
order by to_char(hire_date,'mm');

注意group by使用的原则:

  1. 只有出现在group by子句中的字段,才能单独书写在select子句中。
  2. 没有出现在group by子句中的字段,需要配合组函数书写在select 子句中
  3. 如果group by子句中的字段使用了单行函数,那么select子句中对应的字段也要使用相应的单行函数。

三、having条件筛选子句 【掌握】

  1. having可以针对分组后的数据,再次进行筛选。
  2. 语法: select 字段 … from 表名 where … group by … having … order by;
  3. 案例:

3.1 查询1997年各个月份入职员工人数, 要求人数大于3的月份
① 使用where筛选出1997年入职的员工
② 根据月份进行分组
③ 对分组后的数据使用having进行再次筛选
④ 使用select 生成想要的结果返回

select	to_char(hire_date,’mm’),count(*)
from employees
where to_char(hire_date,’yyyy’)=1997group by to_char(hire_date,’mm’)
having count(*)>3; 

3.1 查询 50、60、90号部门的各自平均工资

  1. 使用having实现:
select department_id,avg(salary)
from employees 
group by department_id
having department_id in(50,60,90);
  1. 使用where实现:
select department_id,avg(salary)
from employees
where department_id in(50,60,90)
group by department_id;

注意: 如果一个需求使用where和having都可以实现时, 优先选择where。

四、select查询语句执行顺序 【重重点】

  1. 完整select语句:
select ... from ... where ... group by ... having ... order by...;
  1. 执行顺序:
    2.1 from 先确定查询的表
    2.2 where 按照条件初次筛选数据
    2.3 group by 根据条件分组
    2.4 having 对分组后的数据再次进行筛选
    2.5 select 生成目标结果集
    2.6 order by 对生成的结果集进行排序

五、Oracle中的伪列

  1. 伪列的概念: 伪列是由Oracle数据库系统维护的一种特殊的列, 并不真实存在于我们的表中,通常我们在使用select *的时候是查询不到的,必须通过手动指定才可以查询到伪列。
  2. 常用的伪列:
    2.1 rowid :
    使用select查询rowid:
select employee_id,first_name,salary,rowid from employees;

2.2 rownum
使用select查询rownum:

select employee_id,first_name,salary,ronum from employees;
  1. rowid 【了解】
    在这里插入图片描述

注意: 如果在知道某一条数据的rowid前提下, 使用这个rowid查询数据效率是最高的, 因为可以根据rowid直接定位到数据存储的位置。 一般开发人员不会显示的使用rowid, oracle数据库会自己决定什么时候使用rowid。

  1. rownum 【重点】

4.1 rownum 是对当前的查询结果集生成的一个自增长的序列号,永远从1开始。
4.2 案例讲解:

1)查询员工表前5名员工的编号、first_name、工资信息

select employee_id,first_name,salary
from employees where rownum<=5;

2)查询员工表第6到第10个人的信息

select employee_id,first_name,salary
from employees where rownum>=6 and rownum<=10;

结果是错误的! 原因是rownum永远是从1开始生成到结果集中。

注意: 当rownum作为where条件判断时,不能做大于或大于等于超过1的运算。 但是可以做 =1 >=1 < <=的关系运算。
4.3 rownum与order by一起使用时的注意事项
-查询工资最高的前5个员工

select employee_id,first_name,salary
from employees where rownum<=5 order by salary desc; //结果也是不对的! 

原因是我们select语句的执行顺序导致。 我们需要的是从按照工资降序排列好的结果集中筛选出前5条数据,但是这条SQL语句是先筛选的数据,然后才进行的order by. 所以拿到的并不是最高工资的前5个人。

解决思路: 我们先按照工资降序排列,生成一个结果集。 然后从这个结果集中筛选出前5个数据。 这里就需要使用后面讲到的子查询来解决。

4.4 select * 与rownum一起使用
1) 如果我们想使用 * 的方式查询出表所有字段信息,同时还要查询rownum,那么必须给表起别名。
2) 查询员工表所有字段的信息,以及rownum的信息

select e.*,rownum
from employees e; // 表起别名的语法:  表名 别名

六、子查询

  1. 子查询也称为嵌套查询, 即在select语句里面还可以在嵌入一个select查询。
  2. 子查询的分类讲解
    2.1 子查询的结果是一行一列 : 将子查询结果作为where的条件。
  • 查询工资高于平均工资人员的信息

① 查询所有人员的平均工资

select avg(salary) from employees;  -result

② 查询工资高于平均工资的人员

select * from employees where salary>result;

③ 合并

select * from employees where salary>(select avg(salary) from employees);

2.2 子查询结果是多行一列:将子查询结果作为where的条件。

  • 查询与first_name是Steven的人在一个部门的人员信息
    ①查询出first_name是Steven人员所在部门的编号
select department_id from employees where first_name=’Steven’;  -result

②查询跟first_name在一个部门人员的信息

select * from employees where department_id in result;

③进行合并

select * from employees 
where department_id in (select department_id from employees where first_name=’Steven’);

2.3 子查询结果是多行多列: 此时我们可以将查询结果作为一张虚表, 对其再次进行查询。

  • 查询工资最高的前5个人的信息
    ①按照工资降序查询
select * from employees order by salary desc;  -tab1

②从按工资降序排序的结果中查询出前5个人

select * from tab1 where rownum<=5;

③合并

select * from (select * from employees order by salary desc)
where rownum<=5;

你可能感兴趣的:(笔记)