Oracle-day4:分组查询(带条件)、DDL建表、约束、主从表

一、内容回顾

复制代码
/*
  ------------------内容回顾----------------------
  --上周内容回顾
  --1、单表的基础查询
    --A、
       select * from emp;
    --B、列的运算 
       --数字类型运算 + - * /
       --函数运算 mod ceil floor round upper lower
       
    --C、取别名--列、表达书取别名
           --*表示所有的列和列同时存在时要写成:表名.*
    --D、表取别名 用表名的地方要用别名替换
    --E、条件筛选 where 
            --比较运算符 > >= < <= <> !=
            --逻辑运算符 not > and > or
            --between A and B  相当于  >=A and <=B
            --日期的表示:date'日期格式字符串','两位天数-中文月份-4位年份',
                               --to_date('日期格式字符串','yyyy-mm-dd')
            --日期的截取to_char(日期,'字符串') yyyy、mm、dd、yyyy-mm-dd
     --F、in和 not in
     --G、空值 is null、非空值 is not null
     --H、条件判断 case when语句
  
  --2、子查询查询要用圆括号括起来
     --A、单行值子查询    比较运算符来连接
     --B、多行值子查询    in或者not in 来连接
     --C、from子查询     用查询取替换表  with as语句、rownum
  
  --3、分组查询
     --A、聚合函数  count(*) sum() avg() max() min()
       --sum()非空求和 
       --avg() 非空求平均值
       --count(列名)非空计数


*/

二、分组查询

sql 复制代码
/*
     ----------------一、分组/聚合函数 ------------------
     分组函数只能从一组的值中计算出一个汇总的信息
     所以在以上给出的查询例题中,分组函数是将查询所获得满足条件的记录行为作为一组
     并返回一个统计值
     如果要想"对多个组分别进行统计汇总"
     例如:分别计算emp表中每个部门职工的最低工资、最高工资、平均和总工资、
     则是要在查询命令中使用到【 group by】子句
     进行分组查询,Oracle会把查询到的行分成多个组,对于每一个组返回一个汇总信息
     
     --------------分组查询的基本语法--------------------
     select 字段名
     from 表名
     [where 过滤条件]
     [group by 字段];
     ---------------
     group by:一致性:在包括 group by 子句的查询中,select子句
     后面的列名表中,除统计聚合函数以外,均应包含在:group by 子句中
     即:列名表中除聚合函数外中不能出现 group by 分组子句,不存在的列名,否则出错
*/

-- 1、计算出公司支付给每个工种的总工资               
-- 1.1 
select job,sum(sal)
from emp
group by job -- 按照工种来分组
;


-- 2、统计各部门的人数、工资总和、平均工资
select deptno,count(deptno),sum(sal),avg(sal) 
from emp
group by deptno
;

-- 3、(多列分组)计算每个部门中每个工种各有多少职工数
select deptno,job,count(*),count(emptno)
from emp
group by deptno,job
;

-- 3.1 带上排序,也是需要group by后面的列名
select deptno,job,count(*),count(empno)
from emp
group by deptno,job
order by deptno,job
;


-- 4、查询员工工资最低为其部门最低工资的员工的编号和姓名及工资
-- 4,1 找出每个部门的最低工资
select deptno,min(sal) minssal
from emp
group by deptno
;

-- 4.2 where 多行子查询
select *
from emp
where (deptno,sal) in(
      select deptno,min(sal) minssal
      from emp
      group by deptno
)
;

三、带条件的分组查询

sql 复制代码
/*
      ------------二、带条件的分组查询
      利用"group by"子句将选择到的进行分组时,
      可以使用 having子句用于限制选择的组(进一步筛选),
      having子句的作用同where子句相似,都是指定查询条件。
      不同的是where子句对行进行选择,检查每条记录是否满足条件,
      而having子句是检查 分组之后的各组 是否满足条件。
      having子句是配合group by子句使用,在没有"group by"子句时不能用,
      并且group by和having子句在命令中要出现在where子句之后。
      --------- 语法 ------------
      select 字段/表达式    
      from 表名 where 单条记录的过滤条件
      group by 字段
      having 分组函数的比较表达式 对group by 分组后的结果进一步筛选 having后面不能使用别名 不能单独使用
      order by 排序;

      ------where 和 having 他们的区别是什么? -------
--1. 先筛选再分组,用使用where筛选,速度上更快
--2. where在group by 之前使用的,having是在group by之后使用的 
--3. where不能筛选聚合函数的结果,having可以
--4、当要求的条件是某个具体的单值条件(条件能在表中查询到)先用where条件筛选,如果是需要通过聚合函数计算得出
     --的条件,先要用group by分组,然后再用having筛选。   
*/
/*
     -----------注意事项--------
1、分组函数只能出现在select、having、order by 子句中
2、如果在select语句同时含有group by、having、orderby,那么他们的顺序是group by、having、order by
3、group by 有一个原则,就是 select 后面的所有字段(除聚合函数外),必须出现在 group by 后面,否则,有语法错误(重要)
4、有having 一定有group by,having筛选时不能使用该查询的别名            

*/

-- 1、查询各工种组的年平均工资,要求每个工种组至少在3人以上(统计3人以上的工种的年平均工资)
-- 1.1 先分组 group by:年平均工资=平均工资*12
select job,avg(sal),avg(sal)*12 yearsal,count(empno),count(*)
from emp
group by job
;

-- 1.2 在分组后进一步筛选:having + 聚合函数
select job,avg(sal),avg(sal)*12 yearsal,count(empno),count(*)
from emp
group by job
having count(empno) >= 3
;




-- 2、查询出至少有两名秘书CLERK的所有部门的部门号和人数,并按人数降序排序。
-- 2.1 先找出所有工种是:CLERK的记录
select * from emp where job = 'CLERK';

-- 2.2 对第一步结果进行分组
select deptno,count(*),count(empno)
from mep where job = 'CLERK'
group by deptno;

-- 2.3 对第二部进行having筛选
select deptno,count(empno) c1,count(*) c2,count(1) c3
from emp
where job = 'CLERK'
group by deptno
having count(empno) >= 2 -- having子句内不能用别名
;

-- 2.4 排序
select deptno,count(empno) c1,count(*) c2,count(1) c3
from emp
where job = 'CLERK'
group by deptno
having count(empno) >= 2 -- having子句内不能用别名
order by count(empno)
;


-- 3、查询出所有经理和销售人员的年平均工资,并按年平均工资降序排序。
-- 3.1 先找出所有的经理和销售员 where
select * from emp where job = 'MANAGER' or job = 'SALESMAN';

-- 3.2 对第一步的结果进行分组 group by
select job,avg(sal),avg(sal)*12 yearavg
from emp
where job in('MANAGER','SALESMAN')
group by job;

-- 3.3 排序 -- 排序可以用别名和表达式的

select job,avg(sal)*12 yearsal
from emp
where job in('MANAGER','SALESMAN')
group by job
order by yearsal desc
;

四、分组练习题

sql 复制代码
-- 三、分组强化练习题 --

--1. 显示平均工资为>2000的职位
select job,avg(sal)
from emp
group by job
having avg(sal) > 2000
;
   
--2. 计算工资在2000以上,职位平均工资大于3000的职位及平均工资
select job,avg(sal) 
from emp
where sal > 2000
group by job
having avg(sal) > 3000
;

   
--3. 找每个部门的最高和最低的工资
select deptno,max(sal),min(sal)
from emp
group by deptno
;
   




--4. 找每个部门中每种职位的最高和最低的工资
select deptno,job,max(sal),min(sal)
from emp
group by deptno,job
order by deptno,job
;   




--5. 显示出工作名称(job)中包含"MAN"的平均工资,最高工资,最低工资及工资总和
select job,avg(sal),max(sal),min(sal)
from emp
where job like '%MAN%' -- 1、先找出包含MAN的记录
group by job
;



   
--6. 显示出20号部门的员工人数
select count(empno)
from emp
where deptno = 20
;   



--7. 显示出平均工资大于2000的部门名称(及平均工资)
-- dept表
   -- deptno 部门编号
   -- dname 部门名称
   -- loc 部门所在地
-- 7.1 先从emp表中查询到平均工资
select deptno,avg(sal) from emp
group by deptno having avg(sal) > 2000;

-- 7.2 子查询筛选
select * from dept
where deptno in(
      select deptno
      from emp
      group by deptno 
      having avg(sal) > 2000
)
;





   
--8. 显示每个部门每种工种平均工资大于2500的部门及工种
select deptno,job,avg(sal)
from emp
group by deptno,job
having avg(sal) > 2500
;



   
--9. 显示出工种名称job中包含"MAN",并且平均工资大于1000的职位名称及平均工资
select job,avg(sal)
from emp
where job like '%MAN%'
group by job
having avg(sal) > 1000
;





   
--10. 列出最低工资大于1500的各种工种
select deptno,min(sal)
from emp
group by deptno
having min(sal) > 1500
;

一、DDL创建普通表

sql 复制代码
/*
  -- 1、创建一个新的表格
  create table 表名(
         列名1 数据类型 约束条件,
         列名2 数据类型 约束条件,
         ...
         列名n 数据类型 约束条件
  );
   -- 1.1 常用的数据类型:number、varchar2、char、date
*/

-- 1、创建一个表
create table user_info(
       user_name varchar2(30),
       user_sex char(3),
       height number(5,2),
       user_time date
);

-- 2、PLSQL用菜单信息创建一个表
-- 导航栏table --> 右键 新建 -- > 创建表格窗口 输入表名
-- --> 列 选项页 -- 填入列名 数据类型 等
-- --> 点击 应用报存按钮 生成表 
select t.*,t.rowid from user_info t;

二、约束

sql 复制代码
/*
       二、约束条件
       --1、唯一约束 unique
                值不能重复,值唯一,但可以为空null
       --2、非空约束 not null
                值不能为空null,但是一个列的值的默认值是可以为空的
       --3、主键 primary key
              常用于唯一标识,一个表中只需要有一个主键key
       --4、检查约束 check
              检查值是否满足某个条件,属于表对象,必须要有名字
       --5、外键 references
              也属于表对象,必须要有名字 主从表
       --6、默认值 default
               当暮云给列指定一个值的时候,该列的值默认为default定义的值,若没有default指定默认值,则是null
       --7、添加注释
       -- 7.1 表注释
       comment on table 表名 is '注释内容'
       -- 7.2 列注释               
       comment on column 表名.字段 is '用户名'
       -- 7.3 删除其注释信息,只需要在 is后设置空字符串即可
           
*/
-- 2.1 创建一个有约束的表
create table user_info3(
       user_id number(8) primary key, -- id 主键约束
       user_name varchar2(30) not null,  -- 非空约束
       user_sex char(3) default '男' check(user_sex='男' or user_sex = '女'), -- 默认值,检查约束
       height number(5,2) check(height>0), 
       user_time date default sysdate -- 默认为系统时间
);


-- 2.2 给info3的表添加注释信息
comment on table user_info3 is '用户信息表user_info3';



-- 2.3 给列添加注释信息
comment on column user_info3.user_id is '用户编号';

-- 2.4 删除表注释信息

-- 2.5 数据字典表
select * from user_col_comments; -- 列的注释信息
select * from user_tab_comments; -- 表的注释信息
select * from user_tables; -- 表在系统中存储的信息

三、外键约束 主从表

sql 复制代码
/*
       三、外键约束 主从表
       作用:保持主从表的数据一致性
*/
-- 3.1 新建主表 班级表
create table class1(
       clsno varchar2(20) primary key,
       clsname varchar2(30) not null unique,
       bz varchar2(20)
);

-- 3.2 新建从表 学生表
create table student1(
       sno varchar2(20) primary key,
       sname varchar2(30) not null,
       ssex char(3) default '男' check(ssex='男' or ssex='女'),
       sage number(3) check(sage>=6),
       bir date,
       clsno varchar2(20) references class1(clsno) -- 每个学生都有一个班级,外键连接的是主表的class1(clsno)列
);

-- 3.3 往class1和student填数据
select c.*,c.rowid from class1 c;
select t.*,t.rowid from student1 t;

四、表练习

sql 复制代码
/*
       四、表练习
*/
-- 练习一、
-- 1、创建 student001表 学生表
create table student001(
       sno varchar2(3) not null primary key,
       sname varchar2(4) not null,
       ssex varchar(2) not null,
       sbirthday date,
       class varchar2(5) not null+2
);

-- 2、创建course表
create table course001(
       cno varchar2(5) not null primary key,
       cname varchar2(10) not null,
       tno varchar(10) not null references student001(sno)
);

-- 3、创建teacher教师表
create table teacher001(
       tnp varchar(10) primary key,
       tname varchar2(20)
);

-- 4、创建 score表
create table score001(
       sno varchar2(3) not null references teacher001(tnp),
       cno varchar2(5) not null references course001(cno),
       degree number(10,1) not null
);

-- 练习二
---主表:
 create table sxb0828(
            ssno char(6) primary key,
            stel number(7) not null check(stel between 6330000 and 6339999)
 );
 
---从表:
 create table stu0828(
                               sno char(6) primary key,
                               sname varchar2(30) not null,
                               ssex char(3) check(ssex='男' or ssex='女'),
                               sage number(3) check(sage >0),
                               mz varchar2(30) default '汉族' not null ,
                               cardid varchar2(18) not null unique,
                               ssno char(6) not null references sxb0828(ssno) 
 );
 --建表先建主表再建从表,删除表时先删除从表再删主表 
相关推荐
冒泡的肥皂2 小时前
MVCC初学demo(一
数据库·后端·mysql
.Shu.3 小时前
Redis Reactor 模型详解【基本架构、事件循环机制、结合源码详细追踪读写请求从客户端连接到命令执行的完整流程】
数据库·redis·架构
薛晓刚6 小时前
当MySQL的int不够用了
数据库
SelectDB技术团队6 小时前
Apache Doris 在菜鸟的大规模湖仓业务场景落地实践
数据库·数据仓库·数据分析·apache doris·菜鸟技术
星空下的曙光6 小时前
mysql 命令语法操作篇 数据库约束有哪些 怎么使用
数据库·mysql
小楓12016 小时前
MySQL數據庫開發教學(一) 基本架構
数据库·后端·mysql
染落林间色6 小时前
达梦数据库-实时主备集群部署详解(附图文)手工搭建一主一备数据守护集群DW
数据库·sql
颜颜yan_7 小时前
企业级时序数据库选型指南:从传统架构向智能时序数据管理的转型之路
数据库·架构·时序数据库
lichenyang4537 小时前
管理项目服务器连接数据库
数据库·后端
沙振宇7 小时前
【数据库】通过‌phpMyAdmin‌管理Mysql数据
数据库·mysql