Oracle

一、简介

Oracle 是甲骨文(Oracle)开发的一个数据库产品

数据库: database , 数据仓库, 用于永久的存储数据(以及数据关系), 并提供对应的访问方式的设备

按照数据结构来组织、存储和管理数据的仓库

二、特点

优势:

  • 功能强大
  • 属于大型数据库(数据存储量大)
  • 用于大型项目架构中

劣势

  • 安装包大, 安装与配置方式复杂, 卸载也十分复杂
  • 启动速度(启动与重启)慢
  • 占用大量系统资源(i7+ / 8G+ )
  • 收费

到目前为止, MySQL 数据库已经能够 支持 大型的项目研发与运行, 所以, 很多公司都在做 去O化,(例如: 阿里), 但是, 还有一部分公司或者项目(三大运营商, 银行)需要使用到Oracle数据库

三、安装

1、直接安装

下载Oracle安装镜像, 直接安装, 注意Oracle的版本

1970 oracle 起家

1980 oracle6

1990 oracle7

1996 oracle8

1999 oracle8i

2002 oracle9i

2003 oracle10g

2007 oracle11g

2008 oracle12c

.....

2020oracle19c

2、安装虚拟机

虚拟机是一台 虚拟的 机器, 准确来说,是一个 虚拟的 操作系统, 也就是说, 使用软件 在你原有的操作系统中, 模拟了另一个独立的操作系统

  • 软件

    • VirtualBox
    • VMWare
    • Docker (更多专业程序员的选择)
  • 另一个操作系统

    • Windows
    • MacOS
    • Linux

T8Q2Je.png

选择Docker的原因:

Docker 会将虚拟机 与 虚拟机中安装的软件打包成一体的镜像, 发布到网站上,程序员可以根据自身需要, 下载对应的镜像文件后运行文件, 从而跳过各种软件的安装与配置步骤, 提高效率

四、几个概念

1、数据库

数据库 是 以 服务 的形式 存在于 操作系统中的

T8QhQA.png

2、数据库客户端

client / 管理软件

是用于管理数据库、执行数据库操作语句(例如:SQL语句)的软件

数据库产品管理软件
MySQLMySQL comman Line client mysql的命令行客户端 cmd
SQLServer内置的可视化管理工具
Oraclesqlplus cmd 命令

除了内置的 或者 自带的 客户端以外 , 还有很多第三方的数据库管理软件, 例如: Navicat

3、SQL

Structured Query Language 结构化查询语言

是一种通用语言, 适用于 几乎所有 主流的 关系型数据库。 是独立存在的, 不依赖于任何数据库产品

在今后的课程中, 如果没有特殊说明, 默认为SQL标准语法

五、登录与退出

1、终端操作

配置oracle环境变量(安装基本自动配置)。

方式1

T8QWzd.png

方式2

T8Q4sI.png

方式3 具有最高权限

T8Q5Lt.png

注意:Oracle 中有一个内置用户 scott / tigger 默认锁定

2、客户端工具操作

T8QoeP.png

六、用户管理

1、创建用户

create user 用户名 identified by 密码;

2、修改用户密码

alter user 用户名 identified by 密码;

3、删除用户

drop user 用户名

七、权限管理

1、场景

T8Q7o8.png

2、简介

Oracle 对于权限管理十分严格, 新创建的用户如果没有分配任何权限, 则无法正常登录使用数据库。需要为 新建的用户分配一定的权限后才可以正常使用

3、权限管理方式

Oracle 使用 角色 来管理权限。即

T8Q6IO.png

使用 角色 管理权限的原因

T8QRRH.png

如果为用户直接赋予权限的话, 需要执行 400 条SQL 语句,工作量极其庞大, 而且容易出错!

T8QydK.png

  • 在Oracle中, 一个用户可以拥有多个角色, 该用户拥有这些角色的所有的权限
  • 为不同的用户角色去设置 不同的 oracle 权限角色是一个很好的习惯!

user : privs 用户:权限

学生s1: 查看成绩

老师t1:录入成绩 查看成绩

教务主任m1:录入成绩 修改成绩 查看成绩


role_student --> 查看成绩

role_teacher --> 录入成绩 查看成绩

role_manager ---> 修改成绩

s1 --> role_student

t1 --> role_teacher

m1 ---> role_teacher role_manager

疑问:

  1. 为什么不将 role_student 给 t1 , 这样的话, role_teacher 中就可以不用写查看成绩了
  2. 为什么不在role_manager 中写录入成绩 查看成绩

class Student

​ private int 查看成绩;

class Teacher

​ private int 查看成绩;

​ private int 录入成绩;

class Manager extends Teacher

​ private int 修改成绩;

4、角色管理

4-1 创建

create role 角色名

4-2 删除

drop role 角色名

4-3 内置角色

名称权限
sys / sysdba拥有所有权限, 即 最高权限
connect可以连接数据库, 可以认为是最低权限
resource一般权限,可以操作数据库对象

5、角色权限管理

5-1 授权

-- 将权限授权给用户/角色 , [该用户可以将这个全选授权给其他用户]
grant 权限 [on 对象] to 用户名/角色名 [with grant option]

5-2 回收

revoke 权限/角色名 from 用户
revoke 权限  from  角色

5-3 权限

-- 注意 使用sysdba去查询
select * from dba_sys_privs;
权限作用备注
create session创建会话, 登录系统权限
create table建表系统权限
create user创建用户系统权限
create sequence创建序列系统权限
create view创建视图系统权限
select / insert/ delete / update / all查询/插入/删除/更新/所有用户权限
  1. 用户对于自己创建的对象(在oracle中, 表、视图、序列、用户... 统称为对象), 拥有该对象的所有权限
  2. 对于其他用户创建的对象, 如果需要访问, 则需要对应的权限, 例如:

sqlplus /nolog

conn / as sysdba

create user ua identified by ua;

create user ub identified by ub;

grant create session , create table to ua;

grant create session to ub;

conn ua/ua

create table t_some (

​ id number

);

select * from t_some ; -- ok

conn ub/ub

select * from t_some; -- 表或者视图不存在!!! userB 确实没有创建t_some 表

select * from ua.t_some; -- 表或者视图不存在!!! 权限不足

conn / as sysdba

grant select on ua.t_some to ub;

conn ub/ub

select * from t_some; ---> 表或者视图不存在!!! userB 确实没有创建t_some 表

select * from userA.t_some; ---> ok

6、用户角色管理

grant 角色 to 用户;
revoke 角色 from 用户;

八、用户创建流程

T8QTdf.png

九、表管理

1、创建表

create table 表名(
    字段名  字段类型  约束,
    字段名  字段类型  约束,
    字段名  字段类型  约束,
);

create table t_test(
    a varchar(20),
    b number(10), -- 2.123456789
    c number(10,4), -- 999999.9999
    d number(10,-4)
);
Oracle类型
varchar2(n)n是数字, 可变长字符串, n是最大长度
number(a,b)表示数字,a表示数值位数(包括整数位和小数位), b 可以省略, 如果b>0, 表示小数部分的位数。如果真实数字超出范围, 四舍五入, 如果b<0, 没有小数位, 小数点左边b位做四舍五入
date日期类型
......
select sysdate from dual; -- 11-Mar-20
select to_char(sysdate,'yyyy-MM-dd HH:mm:ss') as d from dual;

2、查看表结构

desc 表名

3、修改表

了解

alter table 表名 add 列名  类型
alter table 表名 modify 列名  类型
alter table 表名 rename column 旧列名 to 新列名
rename 旧表名 to 新表名
alter table 表名 drop 列名

4、删除表

drop table 表名    

十、约束

0、简介

指的是,对数据库表中的列(字段)的值进行约束, 控制其取值范围

1、非空约束

字段的值不能为空(NULL)

create table t_test2(
    id number not null
)
-- cannot insert NULL into ("ABC"."T_TEST2"."ID")

2、唯一约束

字段的值 不能和 该字段已有的值重复

create table t_test2(
    id number unique
)
--  unique constraint (ABC.SYS_C0011123) violated

3、主键约束

能够唯一 的确定一条数据的列, 我们叫做主键列, 主键列一定是具有主键约束的列

主键约束 即 : 非空约束 + 唯一约束

create table t_test2(
    id number primary key
)

4、外键约束

存在两张表A和B, 如果B表中的字段b_id 的值 来自于 A表中的字段a_id 的值(b_id 的值 只能是 a_id 中的值之一), 那么, 就需要 为 B 表中的 b_id 设置 外键约束, 使其 引用 A 表中的 a_id。此时, A表叫做 主表(被引用表)。

create table t_class (
    id number primary key,
    no varchar2(200)
)

create table t_student (
    id number primary key,
    name varchar2(200),
    class_id number references t_class(id)
)
-- integrity constraint (ABC.SYS_C0011159) violated - parent key not found

5、检查约束

检查约束, 大招, 能够适应一切环境与需求。实际开发中不使用, 应该在 业务代码中和显示逻辑中 进行数据检查

十一、数据库表关系

1、一对多/多对一关系

1-1 案例

  • 班级/学生
  • 公司/部门 员工/部门
  • 类/对象

1-2 实现方式

create table t_dept(
    id number primary key,
    name varchar2(200)
)

create table t_emp(
    id number primary key,
    name varchar2(200),
    salary number,
    dept_id number references t_dept(id)
)

使用外键约束来确定 一对多 或者 多对一的关系

外键在哪张表, 哪张表就是多方

2、一对一关系

2-1 案例

  • 班级/班长

2-2 实现方式

外键约束 + 唯一约束

create  t_class (
    id number primary key,
    no varchar2(200)
)

create table t_monitor (
    id number primary key,
    name varchar2(200),
    class_id number references t_class(id) unique
)

主键当作外键

create  t_class (
    id number primary key,
    no varchar2(200)
)

create table t_monitor (
    id number primary key  references t_class(id),
    name varchar2(200)
)

扩展: 一对一关系其实就是程序设计中的 继承 关系class Monitor extends Clazz

3、多对多关系

3-1 案例

  • 用户/角色

3-2 实现方式

-- 一个用户有多个角色
create table t_role (
    id number primary key,
    name varchar2(200),
    user_id references t_user(id)
)
-- 一个角色对应多个用户
create table t_user(
    id number primary key,
    username varchar2(200),
    password varchar2(200),
    role_id references t_role(id)
)

以上写法是有问题的, 问题是先向哪张表插入数据?

1  role_a    
2  role_b
3  role_c

1 zhangsan  role_a,role_b
2 lisi      role_a,role_c
insert into t_role values (1,'role_a',1) 
-- 》 此时用户表中,还没有数据!也就意味着, 不能从role表开始
insert into t_user values (1,'zjamhsamn','123',1)
-- 》 此时role表中,还没有数据!也就意味着, 不能从user表开始

对于关系型数据库(Oracle 、 MySQL 、SQLServer), 无法直接存储和表示 多对多关系 !!!!!

需要借助中间表, 将 多对多 拆分成两个一对多

create table t_role (
    id number primary key,
    name varchar2(200),
)

create table t_user(
    id number primary key,
    username varchar2(200),
    password varchar2(200),
)

create table t_user_role(
    id number primary key,
    role_id references t_role(id),
    user_id references t_user(id)
)
1  role_a    
2  role_b
3  role_c

1 zhangsan  role_a,role_b
2 lisi      role_a,role_c
t_role 
    1  role_a    
    2  role_b
    3  role_c
t_user
    1  zhanggsan
    2  lisi
t_user_role
    id  user_id role_id
    1    1        1
    2    1        2
    3   2        1
    4    2        3

十二、SQL

以下内容为基础SQL语句, 适用于所有关系型数据库(Oracle, MySQL,SQLServer)

对于数据库中的数据操作, 一般为 增删改查操作 , 简称 CURD 操作

1、插入操作(Create)

insert into 表名 values (列1的值,列2的值,列3的值,列4的值,...)
-- 注意:列n的值 的 个数和顺序要和数据库表总的列完全一致
insert into 表名 (列1,列2,列3, ...) values (列1的值,列2的值,列3的值,...)
-- 向表中的 特定列 插入数据, values 后的值 只需 和 values前的 列 的个数 、顺序一致即可

2、更新操作(Update)

-- 更新所有的数据
update 表名 set 列名=值,列名=值,列名=值...
-- 更新部分数据 where 部分和查询操作的 where部分一致
update 表名 set 列名=值,列名=值,列名=值... where xxx

3、查询操作(Read)

-- 查询表中的所有数据
select * from 表名
-- 查询表中所有数据的特定列
select 列1,列2,列3... from 表名

4、删除操作(Delete)

-- 删除表中的所有数据
delete from 表名
-- 删除表中的部分数据 where 部分和查询操作的 where部分一致
delete from 表名  where xxx

十三、查询操作

0、准备工作

create table t_dept(
    id number primary key,
    name varchar2(200)
);

create table t_emp(
    id number primary key,
    name varchar2(200),
    salary number,
    dept_id number references t_dept(id)
);

insert into t_dept values (1,'市场部');
insert into t_dept values (2,'行政部');
insert into t_dept values (3,'财务部');
insert into t_dept values (4,'渠道部');

insert into t_emp values (1,'王龙飞',6000,1)
insert into t_emp values (2,'张超',4000,2)
insert into t_emp values (3,'aguang',5000,1)
insert into t_emp values (4,'罗广',3500,3)
insert into t_emp values (5,'郑果',1800,4)
insert into t_emp values (6,'李硕',600,4)
insert into t_emp values (7,'周恒宇',6000,3)
insert into t_emp values (8,'索文超',601,1)
insert into t_emp values (9,'X',10000,NULL)

1、基础查询

select * from t_emp; -- 实际开发中禁止使用, * 效率低 可读性差
select id,name,salary,dept_id from t_emp;

2、条件查询

select * from t_emp where 查询条件 
-- 满足查询条件A 并且 满足查询条件B 的所有数据
select * from t_emp where 查询条件A  and  查询条件B
-- 满足查询条件A 或者 满足查询条件B 的所有数据
select * from t_emp where 查询条件A   or 查询条件B

关于 查询条件

  • 是一个bool类型表达式(true | false类型的表达式)
  • 表达式中可以用的运算符有

    • 常规: =,>,<,>=,<=,!=,+,-,*,/,% , <> 不等于
    • 特有运算符

      • in: 给出枚举值(固定且有限个值), 取值必须在给定的值中

        -- 查询所有薪资为4000、5000或者6000的
        -- select * from t_emp where salary = 4000 or salary = 5000 or salary = 6000
        select * from t_emp where salary in (4000,5000,6000);
- `not in` : 与 `in` 相反
 select * from t_emp where salary not in (4000,5000,6000);
- `between x and y`: 取值在[x,y]
-- select * from t_emp where salary >= 4000 and salary <= 6000;
select * from t_emp where salary BETWEEN 4000 and 6000;
- `is null / is not null` 与NULL值进行比较的唯一途径

  这是一个错误的SQL, 注意:**任何值与NULL做比较, 结果都是NULL。**
select * from t_emp where dept_id = NULL;
select * from t_emp where dept_id is NULL;
select * from t_emp where dept_id is not NULL;
  • 不一定要和列有关

    select * from t_emp where 1 = 1; -- 查询所有数据
    select * from t_emp where 1 != 1; -- 查不到任何数据

3、为查询结果取别名

-- 查询所有员工的姓名和年薪
select name,salary,salary*12 as year_salary from t_emp 

as关键字可以省略

select name,salary,salary*12  year_salary from t_emp 

如果别名中有空格, 需要使用 双引号(oracle) 将别名引起来

select name,salary,salary*12 "year salary" from t_emp 

4、去除重复数据

-- 查询员工分布在哪些部门, 展示这些部门的部门id
select distinct dept_id from t_emp;
-- distinct 后如果有多个列, 作用是联合去重
select distinct dept_id,name from t_emp;
-- 相当于 select distinct (dept_id,name) from t_emp;

5、排序

正序 升序

-- 根据薪资 正序排序 从小到大
select * from t_emp order by SALARY asc
-- asc 可以省略, 默认排序规则是asc
select * from t_emp order by SALARY 

倒序 降序

select * from t_emp order by SALARY desc

可以对多个列进行排序

order by 列A  排序规则, 列B 排序规则,.....

按照薪资升序排序, 如果薪资相同, 按照部门id 降序排序

select * 
from t_emp 
order by SALARY  , DEPT_ID desc
-- salary 后省略了一个asc

Oracle :在order by中 ,null 是 最大值 -> nvl(col,defaultValue) 函数

select * 
from T_EMP
order by nvl(dept_id,-1) desc;

MySQL:在order by中 ,null 是 最小值 -> ifnull(col,defaultValue)

select * 
from T_EMP
order by ifnull(dept_id,-1) desc;

6、模糊查询

使用 like 替代 = , 作为比较运算符参与查询

select * 
from T_EMP
where salary like '%6%'

like 需要配合 占位符使用

  • % : 匹配任意长度的字符(包括0个字符)
  • _: 匹配一个字符
  • MySQL: \: 转义字符, 用于转义 % , _', \

    select * 
    from t_emp
    where name like '%a_%a' escape 'a';

十四、查询操作-组函数

又名 聚合函数, 用于对数据(一般是数值类型数据)进行分组计算

  • 只能用于select后, 或者 having
  • null 值不参与组函数运算
组函数作用
max(列)最大值
min(列)最小值
sum(列)
avg(列)平均
count(列)计数

查询所有员工的最高薪资

select 
    max(salary)
from 
    t_emp
-- 10000 null 值不参与组函数运算

查询所有员工的最低薪资

select 
    min(salary)
from 
    t_emp;
-- 600 null 值不参与组函数运算

查询所有员工的薪资和

select 
    sum(salary)
from 
    t_emp

查询所有员工的平均薪资

select 
    avg(salary)
from 
    t_emp
-- null 不参与运算
-- null 参与运算  值为0
select 
    ROUND(avg( nvl(salary,0) ), 2)
from 
    t_emp

统计员工人数

count 计数, 记录的是 没有count时, 查询结果中所包含的数据条数

select  count(*) from     t_emp;
select  count(id) from     t_emp;
select  count(nvl(salary,1)) from     t_emp;
select  count(1) from     t_emp;
select 
    count( distinct nvl(dept_id,-1) ) as c
from
    t_emp;

十五、分组查询

1、一个错误的SQL

select 
    avg(SALARY) , name 
from
    t_emp;
> ORA-00937: not a single-group group function

两列 列的数据长度不一致, 在Oracle中, 是要报错的

2、简介

分组查询, 指的是, 根据某个列或者某几个列的值,将相同值的数据分为一组。变成一条数据。

分组前数据

姓名性别年龄
张三30
李四30
老王20
LS未知73

按照性别分组, 只展示性别和年龄

性别年龄
30(其实是两个30)
20
未知73

按照性别分组, 展示性别和姓名

姓名性别
???
老王
LS未知

和 15 - 1 一样的问题,两列的数据长度不一致 ,Oracle报错,解决方案是:

  • 去掉长度不一致的列
  • 把一组中值不一致的数据合并:把多个列的值合并成一个列的值, 使用组函数(聚合函数)
  • 让数据不一致的列也参与分组

3、语法

SELECT 
FROM
[WHERE]
GROUP BY 列名A,列名B.. 
[HAVING]
[ORDER BY]

注意: select 后的列, 要不然出现在 group by 中, 要不然使用聚合函数

4、案例

  1. 查询所有员工的平均薪资

    select avg(SALARY) from T_EMP
  2. 查询每个部门的员工的平均薪资

    select 
        avg(SALARY) , dept_id 
    from 
        T_EMP
    group by dept_id
  3. 查询每个部门的员工的平均薪资 - 2

    select 
        avg(SALARY) , dept_id , wmsys.wm_concat(name)
    from 
        T_EMP
    group by dept_id
  4. 查询每个部门的员工的平均薪资, 没有部门的除外

    select 
        avg(SALARY) , dept_id 
    from 
        T_EMP
    where
        dept_id is not null
    group by dept_id
  5. 查询每个部门的员工的平均薪资, 没有部门的除外, 按照部门降序排序

    select 
        avg(SALARY) , dept_id 
    from 
        T_EMP
    where
        dept_id is not null
    group by 
        dept_id
    order by 
        dept_id desc
  6. 查询每个部门的员工的平均薪资, 没有部门的除外, 按照平均薪资降序排序

    select 
        avg(SALARY) , dept_id 
    from 
        T_EMP
    where
        dept_id is not null
    group by 
        dept_id
    order by 
        avg(SALARY) desc
  7. 查询 平均薪资>2000的所有部门, 要部门编号和平均薪资

错误写法

select 
    avg(SALARY) , dept_id 
from 
    T_EMP
where 
    avg(salary) > 2000
group by dept_id

ORA-00934: group function is not allowed here

聚合函数 不能出现在 where 后, 如果将聚合函数作为查询条件:

  • 没有分组查询: 需要使用子查询
  • 有分组查询, 使用having关键字

  1. avg(SALARY) , dept_id 
  2. T_EMP
  3. by

    dept_id
  4. avg(salary) > 2000

十六、多表查询

1、概念及分类

多表查询指的是, 将多张表的数据, 按照某种逻辑关系, 联系在一起,进行查询操作

分类:

  • 子查询

    • 关联子查询
    • 非关联子查询
  • 连接查询

    • 左连接
    • 右连接
    • 内连接
    • 全连接
    • 笛卡尔积

2、准备工作

CREATE TABLE T_DEPT (
  ID NUMBER NOT NULL ,
  NAME VARCHAR2(200 BYTE) 
)

CREATE TABLE T_EMP (
  ID NUMBER NOT NULL ,
  NAME VARCHAR2(200 BYTE) ,
  SALARY NUMBER ,
  DEPT_ID NUMBER ,
  MANAGER_ID NUMBER 
)

十七、子查询

1、概念

子查询指的是, 在 一个 查询结构中 select from where group by having 嵌套了另一个查询结构

2、非关联子查询

一个查询A 嵌套在 另一个查询B的 where / having 关键字后,此时, A 称为 B的 非关联子查询

即: A B 两个查询没有逻辑上的数据关联。是 从一个查询结果中进行查询

例如: 查询工资最低的员工的 姓名和工资值

select
    name,salary
from
    t_emp
where 
    salary = (
        
        select min(salary) from t_emp
    
    )

3、关联子查询

一个查询A 嵌套在另一个查询B的 select 后或者 from 后, 此时, A 称为B的 关联子查询

例如: 查询所有的部门信息以及每个部门的人数

注意: 如果一个查询中出现多张表, 那么为每一张表取别名, 并通过别名访问表中的字段是一个很好的习惯

Oracle要求, 必须为 每个关联子查询的结果 命名

select
    d.id , d.name , (select 
                         count(1) 
                     from 
                         t_emp  e 
                     where e.dept_id = d.id)  c
from
    t_dept  d

例如: 查询所有员工的 自己的薪资 和 该员工所在部门的平均薪资

select 
    e.name, e.salary , (

                select
                    avg(salary)
                from
                    t_emp e1
                where
                    e1.dept_id = e.dept_id

    ),e.dept_id
from
    t_emp e

例如:

  • 查询每个部门 工资最低的员工的 姓名和工资值
  • 找出人数最多的部门的部门名称
  • 找出哪些部门的平均薪资比索文超 所在部门的平均薪资要高, 展示 部门编号和平均薪资, 按照平均薪资降序排序

十八、连接查询

1、简介

所谓的连接查询, 指的是, 将多张表的数据, 按照某种规则 连接在一起, 拼接成一条数据, 最终组成查询结果。实现方式, 主要包括

  • 笛卡尔积
  • 内连接
  • 外连接

    • 左[外]连接
    • 右[外]连接
  • 全连接

2、笛卡尔积

  • 概念

笛卡尔积本身是一天个数学上的概念,两个集合X,Y的笛卡尔积为 X * Y

A ✖ B = { (x,y) | x ∈ A ^ y ∈ B }

A {a,b} B {0,1,2}

A * B = { (a,0),(a,1),(a,2),(b,0),(b,1),(b,2) }

在Oracle 中, 笛卡尔积指的是, 将一张表A的每一条数据, 与 另一张B 的每一条数据进行 无条件连接, 得到最终的结果。

  • 语法

    select * from A,B
  • 示例

    select * from t_emp , t_dept
  • 笛卡尔积本身的结果,并不是全部有意义的
  • 可以使用where条件进行数据的筛选
select * from t_emp e , t_dept d where e.dept_id = d.id
select * from t_emp e , (
    select min(e2.salary) s , e2.dept_id
    from t_emp e2 
    group by e2.dept_id 
) d where  nvl(e.DEPT_ID,-1) = nvl(d.DEPT_ID,-1) and e.SALARY = d.s

实际开发中, 不到万不得已, 不使用笛卡尔积

3、[内]连接

  • 概念

内连接指的是, 将A表中的每一条数据, 与B表中的每一条数据 根据连接条件 进行连接, 不满足连接条件的数据被舍弃

  • 语法

    select * from A  [inner] join B on 连接条件
  • 案例

    select 
        *
    from 
        t_emp e 
    inner join t_dept d on e.dept_id = d.id

渠道部有哪些员工, 需要员工姓名和薪资

select 
    e.name , e.salary
from 
    t_emp e 
inner join t_dept d on e.dept_id = d.id
where d.name = '渠道部'
select
    e.name,e.salary
from
    t_emp e , t_dept d 
where
    e.dept_id = d.id and
    d.name = '渠道部'

错误写法, 不是语法错误, 不能看着数据写sql

select 
    e.name , e.salary
from 
    t_emp e 
where
    e.dept_id = 4

4、左[外]连接

  • 概念

内连接的数据 + 左边表(from的表)中不满足连接条件的数据, 右边表部门补NULL

  • 语法

    select * from A left [outer] join B on 连接条件

注意: [ ] 表示 里面的内容可有可无, 并不是sql中有一个[ ]

select * from A a, B b where a.id = b.a_id(+)
  • 案例

    select 
        *
    from 
        t_emp e 
    left join t_dept d on e.dept_id = d.id;
select
    *
from
    t_emp e , t_dept d
where
    e.dept_id = d.id(+)

查询结果中 包括了左边表中不满足连接条件的数据

T8QbFS.png

5、右[外]连接

  • 概念

内连接的数据 + 右边表(join的表)中不满足连接条件的数据,左边表员工补NULL

  • 语法

    select * from A right [outer] join B on 连接条件

注意: [ ] 表示 里面的内容可有可无, 并不是sql中有一个[ ]

select * from A a, B b where a.id(+) = b.a_id
  • 案例

    select 
        *
    from 
        t_emp e 
    right join t_dept d on e.dept_id = d.id;
select
    *
from
    t_emp e , t_dept d
where
    e.dept_id(+) = d.id

查询结果中 包括了右边表中不足连接条件的数据

T8QqJg.png

6、全连接

MYSQL 不支持。

  • 概念

内连接的数据 + 右边表(join的表)中不满足连接条件的数据,+ 左边表(join的表)中不满足连接条件的数据,

  • 语法

    select * from A full [outer] join B on 连接条件

注意: [ ] 表示 里面的内容可有可无, 并不是sql中有一个[ ]

  • 案例

    select 
        *
    from 
        t_emp e 
    full join t_dept d on e.dept_id = d.id;

查询结果中 包括了左右边表中不足连接条件的数据

7、连接查询写法

  1. 写架子 : select from where
  2. 我要什么: 写在select 后, 注意,加别名 x.xxx
  3. 我有什么: 写在where后
  4. 完善语法, 选择连接方式

8、总结

T8QLWQ.png