Oracle

一.引言

  1. 为什么学习数据库?(对数据进行持久化(persistence)存储)

    • 变量,数组,对象,集合

      缺点:不能长久保存数据

    • 文件,通过io读写

      长久保存数据

      缺点:无法控制并发,效率低

    • 数据库解决上述问题

      存储大量数据,长久保存,支持并发,数据安全,访问简单

  2. 数据库的分类:

    • 关系型数据库:Oracle|DB2|MySql|SqlSever...

    • 对象型数据库 : Object Database

    • 非关系型数据库 :Redis|mongDB

  3. 数据库存储数据的结构

  4. 二.Oracle数据的安装

    计算名配置:C:oraclexeapporacleproduct10.2.0serverNETWORKADMIN

    OracleServiceXE:Oracle数据库的核心服务

    OracleXETNSListener:Oracle数据库的对外服务

    三.Oracle数据库的相关概念

    • Oracle数据库:关系型数据库管理系统---RDBMS

    • 数据库:存储和管理数据(database)--DB

    • 用户:hr

    • 表:table,真正存储和管理数据

    • 行: row,代表数据库的一条数据,对象(Object),实体(entity),记录(record)

    • 列:column,代表所有数据的一个属性,单元格(一个对象的一个属性),字段(Field),键(Key)

    • 主键:primary key,一行数据的唯一标识

    • 外键:foreign Key,多张表之间的联系

    四.基本查询

    1. 简单查询

    2. --查询表内所有信息 --单行注释 /*多行注释*/ select * from Employees; /*常见错误 表或视图不存在:表明写错了 未找到要求的 FROM 关键字,无效的Sql语句:查询结构不完整 */ /* *不建议使用 *先匹配成每一列的名字,然后再查询 *会找出无用数据,降低想查询效率 *可读性差 */ --开发使用,查询所有列名称 select Employee_id,First_name,Last_name,Email,phone_number,hire_date,job_id,salary,commission_pct, manager_id,department_id from Employees;
  5. --查询部分列信息
    --查询工号,名字,工资信息
    select employee_id,first_name,salary from employees;
    --对列数据进行运算 + - * /
    --查询所有员工年薪
    select employee_id,first_name,salary*12 from employees;
    --给列起别名 [as] 列别名
    --查询所有员工年薪
    select employee_id as 工号,first_name 名字,salary*12 as 年薪 from employees;
    注:如果列别名使用关键字或者中间存在空格,别名需要使用"列别名

      2.排序 order by 

--基本语法
select ... from 表名 order by 排序条件
--按照工资降序查询员工信息
select * from employees order by salary desc;
注:asc升序排序(默认)desc降序排序 
--按照工资升序查询员工信息,工资相同按照入职时间排序
select * from employees order by salary ,hire_date;
注:如果 order by 后有两个字段,表示如果按照第一个字段排序完成后,第一个字段相同的情况下,按照第二个字段排序

   

  1. 条件查询

    • 基础语法

      select...from...where...
      原理:先将基表加入缓存,然后使用基表的每一条数据与过滤做运算,满足显示,不满足删除
    • 比较查询 > < >= <= != =

      --查询工号105的员工信息
      select * from employees where employee_id=105;
    • 多条件查询 and or

      --查询部门编号为80且工资大于12000的员工信息
      select * from employees where department_id=80 and salary>12000;
      --查询部门编号为60,80,90的员工信息
      select * from employees where department_id=60 or department_id=80 or department_id=90;
    • 空值判断 is [not] null

      --查询部门经理为空的员工信息
      select * from employees where manager_id is null;
      --提成不为空的员工信息
      select * from employees where commission_pct is not null;
    • 区间处理 [not]between and

      --查询工资大于8000小于10000的员工信息
      select * from employees where salary>=8000 and salary<=10000;
      select * from employees where salary between 8000 and 10000;
      注:小值在前,大值在后
    • 枚举查询[not]in

      --查询部门编号为60,80,90的员工信息
      select * from employees where department_id=60 or department_id=80 or department_id=90;
      select * from employees where department_id in(80,60,90);
      注:判断的数据为非null值
    • 模糊查询 [not]like

      --查询姓氏以“K”的员工信息
      select * from employees where last_name like 'K%';
      --%:表示任意字符0--n
      select * from employees where last_name like '____y';
      --_:表示单个字符
      注:字符串常量严格区分大小写
    • 分支查询 case when then else end

      --显示数据工资大于10000为高收入,工资>6000为中等收入,工资<=6000低收入
      select employee_id,first_name,salary,
      case
      when salary>10000 then '高收入'
      when salary>6000 then '中等水平'
      else '低收入'
      end as 收入水平
      from employees

五.函数

  1. 单行函数

    在单行函数的作用下每一个数据返回一个数据,表中有107行数据,单行函数运行完毕,返回107行数据

    • 常用的单行数据 mod() length()

      --显示员工工资以千单位
      select employee_id,first_name,salary,mod(salary/1000,1000) from employees;
      select mod(15,4) from dual;
      --dual:哑表,虚表,没有意义,为了保证Sql语句的完整性
      --查询所有员工名字的长度
      select first_name,length(first_name) from employees;
      select length('hjxdfhjsadgfhhjgsdfghjsgdhjf') from dual;
    • sysdate:获取当前系统时间

      select sysdate from dual
    • to_char(时间,时间格式)

      --作用:指定时间格式,获取时间的部分数据
      时间字符串格式:
      yyyy:年
      mm:月
      dd:日
      hh24:24小时制显示时
      mi:分
      ss:秒
      day:星期几
      --展示员工入职月份
      select employee_id,first_name,hire_date,to_char(hire_date,'mm') from employees
    • to_date(时间字符串,时间格式)

      --作用:将给定的日期转为指定格式的日期类型,进行运算(默认以天为单位进行运算的),默认显示效果(dd-mm月-yy)
      --显示2028-8-6是周几
      --to_date('2028-8-6','yyyy-mm-dd'):将日期字符串转为日期类型
      --to_char(to_date('2028-8-6','yyyy-mm-dd'),'day'):获取当前时间的是周几的部分
      select to_char(to_date('2028-8-6','yyyy-mm-dd'),'day') from dual;
  2. 组函数

    组函数:作用于提前分好的组数据,有一组数据执行一次函数,有几组返回几组数据

    • sum avg max min

      --(列名):统计当列的数据之和
      --统计员工工资之和
      select sum(salary) from employees;

      --avg(列名):平均值
      --统计员工平均工资
      select avg(salary) from employees;

      --max(列名):最大值
      --统计员工最高工资
      select max(salary) from employees;

      --min(列名):最小值
      --统计员工最低工资
      select min(salary) from employees;
    • count计数

      --count(列名):统计列的数据条数
      --对该列的非null值计数

      --统计有部门的员工人数
      select count(department_id) from employees;

      --统计有提成的员工人数
      select count(commission_pct) from employees;

六.分组

  1. 107条数据根据一定条件分为若干个组,进行组内统计(组函数)

  2. 基本语法

    select...from...group by...
    --查询每个部门多少人
    select department_id,count(*) from employees group by department_id;
    --第一步:先进行分组
    --第二步: 统计人数
  3. 注:

    • 只有出现在group by 后面的列名,才能查询

    • 没有出现在group by后面的列,查询时必须配合组函数

    • select 使用的函数必须是出现在group by后面的函数

    • case when 条件bai1 then 结果1 when 条件2 then 结果du2 .......... else 结果n end
      就是zhi满足条件1时,输出dao结果1,满足条件2时输出结果2,
      如果条件都不满足,输出结果n
    --分组统计数据工资大于10000为高收入,工资>6000为中等收入,工资<=6000低收入的人数
    select
    count(*),
    case
    when salary>10000 then '高收入'
    when salary>6000 then '中等收入'
    else '低收入'
    end 收入水平
    from employees
    group by
    case
    when salary>10000 then '高收入'
    when salary>6000 then '中等收入'
    else '低收入'
    end
  4. having 语句

    作用:对分组后的结果进行过滤

    --统计1996年每月入职员工人数大于1的月份
    select to_char(hire_date,'mm'),count(*)
    from employees
    where to_char(hire_date,'yyyy')=1996--完成1996的筛选
    group by to_char(hire_date,'mm')--完成分组
    having count(*)>1--完成入职人数>1的筛选
    --where count(*)>1--完成入职人数>1的筛选 error!
    • having 和where区别

      • where对原始表中数据进行过滤

      • having对分组后的数据进行过滤

      • 在sql语句中既可以使用where 又可以使用having,首选where ,where 效率高

      • 注:组函数不能用在where字句中

七.小结

  • 书写顺序:

    select...
    from...
    where...
    group by...
    having...
    order by...
  • 运行顺序

    from:确定查询原始表
    where:对原始数据进行过滤
    group by:对留下的数据进行分组
    having:对分组数据进行过滤操作
    select:对留下的数据进行相关查询及运算
    order by:对运算后数据进行排序

一.伪列

  • rowid

    • 表中数据一行的唯一标识,根据表中数据的物理地址计算得来。应用:索引

  • rownum(相当于excle的计数列,第一行,第二行....)

    • 自动对查询结果做一个编号,符合条件的数据计数,第一条,第二条...

    --查询表内前5名员工
    select * from Employees where rownum<=5;
    --查询表内6--10的员工信息
    select * from employees where rownum>5 and rownum<11;-- error rownum>5
    select * from employees where rownum>=1;--true
    select * from employees where rownum>=10;-- error rownum>=10
    注:romnum只能进行< <= >=1,不能进行>n,>=n

    --查询表内所有数据和伪劣
    select *,rownum from employees;--error ,*号只允许存在一列
    select rownum,employees.* from employees;--使用表名.*是所有数据和其他数据共存
    select rownum,e.* from employees e;--简化表名的写法,给表起别名
    注:给表起别名不能使用 as

二.子查询

  • 子查询:在一个完整select语句中嵌套其他的完成的select语句,称内部select语句为子查询,外部select语句为主查询。

  • 子查询的结果为单个值(1行1列):把子查询结果当成一个值,带入主查询参与运算

    --查询最高工资的员工信息
    --步骤一:找出最高工资--24000
    select max(salary) from employees;
    --步骤二:找出员工信息--where
    select * from employees where salary=24000;
    --合并Sql
    select * from employees where salary=(select max(salary) from employees);
  • 子查询的结果多个值(N行1列):把子查询的结果当成一个范围,带入主查询参与运算

    --查询姓‘King’的部门的同部门员工
    --步骤一:查出姓‘King’所在的部门
    select department_id from employees where last_name='King';
    --步骤二:查询80 90 部门的所有员工
    select * from employees where department_id in(80,90);
    -- 步骤三:合并SQL
    select * from employees where department_id in(select department_id from employees where last_name='King');
  • 子查询的结果为一个表(N行N列):把子查询的结果当成一张表,继续进行筛选

    --查询工资前5名
    select * from employees where rownum<=5 order by salary desc;--error
    --步骤一:按照工资排序降序--tb1
    select * from employees order by salary desc;
    --步骤二:从表1找出前五条数据
    select * from tb1 where rownum<=5
    --步骤三:合并sql
    select * from(select * from employees order by salary desc)where rownum<=5;
  • 分页查询:【重点】

    --查询工资前6-10名
    --步骤一:对工资排序查所有人信息
    select * from Employees order by salary desc;--tb1
    --步骤二:查询前十条数据+伪劣
    select rownum,tb1.* from tb1 where rownum<=10;--tb2
    --步骤三:查询rownum>=6
    select * from tb2 where rownum>=6
    --合并前两个
    select rownum ,tb1.* from
    (select * from Employees order by salary desc) tb1
    where rownum<=10;
    --合并所有
    select * from 
    (select rownum r,tb1.* from
    (select * from Employees order by salary desc) tb1
    where rownum<=10)
    where r>=6;
    分页SQL(第n-m)步骤总结:
        --步骤0:对原始数据进行筛选
        --步骤1:查询符合条件的<=m的所有数据作为新表,表中需要展示rownum,起别名 rn
        --步骤2:查询得到表的rn>=n的数据
        --步骤3:合称SQL

    三.连接查询

    • 连接查询:要查询的数据来自于多张表,可以做表连接

    • 基本语法:

      select ...
      from 表1
      [...]join 表2
      on 连接条件
      --多张表做连接查询:
      列数:表1列数+表2列数+...
      行数:取决表连接方式
    • 内连接【重点】

      --关键字:[inner] join
      --查询刘克的信息+老师的信息
      特点:
      结果:符合连接条件的数据
      必须连接条件
      2张表没有顺序要求
      select s.*,t.* from student s
      inner join teacher t
      on s.teacherid=t.teacherid
      where stuname='刘克';
      --查询king 工号,名,工资,部门编号,部门名称
    • 外链接

      • 左向外连接:左连接

        --关键字:left [outer] join
        --查询所有学生信息和所在教室的信息
        select s.*,c.*
        from Student s
        left join Clazz c
        on s.clazzid=c.clazzid
      • 右向外连接:右连接

    • 右向外连接:右连接

      --关键字:right [outer] join 
      --查询所有班级及班级内学生的信息
      select s.*,c.*
      from student s
      right join clazz c
      on s.clazzid=c.clazzid
    • 完全外连接

      --full [outer] join
      --查询所有班级及学生的信息
      select s.* ,c.*
      from student s
      full join clazz c
      on s.clazzid=c.clazzid;

  • 交叉连接

    关键字:cross join
    无条件连接(表1rownum*表2rownum),笛卡儿积,毫无意义
  • 自连接(特殊的表连接)

    关键字:join
    --查询哈哈的信息和哈哈组长的信息
    select s1.*,s2.*
    from student s1
    join student s2
    on s1.leader=s2.studentid
    where s1.stuname='哈哈';
  • 多表连接

    关键字:join
    --查询刘克的信息+班级信息+老师信息
    select s.*,c.*,t.*
    from student s
    join clazz c
    on s.clazzid=c.clazzid
    join teacher t
    on s.teacherid=t.teacherid
    where s.stuname='哈哈';

SQL语句体系

  • SQL:(Structured Query Language)结构化查询语言,Oracle/mySQL/SqlServer...可以用在RDBMS中管理数据;PL/SQl:Oracle数据库的工具;PL/SQl:Oracle公司在SQL语言上的扩展

  1. DQL:(Data Query Language)数据查询语言

    例:select[重点]

  2. DDL:(Data Define Language)数据定义语言

    例:create/drop/alter--表

    • 创建表

       

      • 表名--望文生义

        create table 表名(
          列1,
          ...
          列n
        );
        • 语法

          列名 数据类型 约束,
          注:列名--望文生义,多个单词组成列名,由_隔开
        • 数据类型

           

        • 约束:对列的内容要求

    • 删除表

      drop table 表名;
      注:如果当前表有列被其他表引用作为外键,先删除引用表,再删除当前表
      暴力操作: drop table 表名 cascade constraints;--删除当前表和引用表的外键约束
    • 修改表

      • 修改列类型

        alter table 表名 modify 列名 类型;
        注:表内没有数据可以修改
      • 修改列名

        alter table 表名 rename column 旧列名 to 新列名;
      • 追加新列

        alter table 表名 add 列名 类型 约束;
  3. DML:(Data Modify Language)数据修改语言

    例:insert/delete/update--记录

    • 增加数据

      insert into 表名(列名1,列名2,...) values(值1,值2...);
      注:列名和值依次匹配
      --执行完insert,必须执行commit,数据才能添加至数据库,否则数据仅仅被验证可以添加,放在缓存区而已(回滚段)
    • 删除数据

      delete from 表名;--删除表中全部数据
      delete from 表名 where 条件删除;--删除表中指定数据
    • 修改数据

      update 表名 set 列名=值;--修改一列所有数据
      update 表名 set 列名=值 where 修改条件;--修改指定字段
  4. TCL:(transaction Control Language)事务控制语言

    例:commit/rollback--提交/回滚

    1. 事务

      保证业务操作完整性的一种数据库机制

      (事务时数据库执行的最小单元,通常由一个或者多个Sql组成,并且在一个事务中SQl,要成功需要一起commint;如果有一条失败,都失败rollback)

    2. 命令

      commit;提交事务--把回滚段数据持久化到数据库

      rollback;撤销事务--把回滚段中的数据删除

    3. 事务的边界

      • 事务的开始:一个业务(事务)的第一条SQL语句开始

      • 事务的结束:提交或者回滚事务

      • 提交或者回滚事务方式:

        • DDL内含事务控制,只要执行,那么直接commit;

        • DML事务提交必须手动执行commit,不成功手动执行rollback;

        • DML事务使用SQLPlUS时,如果使用exit;正常退出,存在于回滚段中的数据自动commit;如果非正常退出命令窗口,存在于回滚段的数据执行rollback;

      • 图例:

    4. 原理:

       

    5. 事务的特性ACID[了解 面试]

      A:原子性--一组Sql语句,一起成功,一起失败,完整整体

      C:一致性--保证用户数据操作前操作后的一致

      I:隔离性--保证多线程并发的数据安全

      D:持久性--事务操作的数据持久化到数据库

二.数据库中的其他对象

  1. 序列

    • 作用:自动的生成一段有顺序的数字

    • 语法:

      create sequence 序列名 --生成序列,序列名:表名_列名_seq/seq_表名_列名
      [start with n]--数字n开始
      [increment by m];--递增m
    • 使用:通常用在主键上,添加数据时使用序列名.nextval获取序列的下一个值

      --创建序列
      create sequence seq_card_id start with 1 increment by 1;
      --插入数据
      insert into t_card values(1,123456,'666666',1000.0);--没有添加序列前
      insert into t_card values(seq_card_id.nextval,456789,'777777',999.9);--添加序列后
    • 注:

      序列生成后可以使用在所有表,所有列,数据一旦使用无法再次生成

    • 删除序列

      drop sequence 序列名;
  2. 视图

    • 作用:起了名字的select语句

    • 语法:

      create view 视图名 as select...;生成一个视图
    • 使用:

      select * from 视图名;
    • 删除视图:

      drop view 视图名;
    • 注意:

      • 通过视图查询不能提高查询效率(简化SQL)

      • 只是保存 查询列,没有生成新的库表结构

      • 不建议使用通过视图的insert/delete/update

  3. 索引

    • 作用:提高查询效率

    • 语法:

      create index 索引名 on 表名(字段名);
    • 自动使用

    • 删除索引

      drop index 索引名;
    • 注意:

      • 主键列和唯一列(unique)自动增加索引

      • 通常在 大量数据 中查询 小量数据,经常查询的列上增加索引

      • 索引不是越多越好,原因:索引占用内存 DML:维护索引





以粮为纲全面发展
原文地址:https://www.cnblogs.com/alexliuf/p/13785940.html