欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

笛卡尔积与多表查询

程序员文章站 2024-03-22 13:56:28
...

笛卡尔积与多表查询

笛卡尔积是关系代数中的概念, 是 DB 中多表连接的理论基础; 本文通过 demo 演示常见的四种多表连接


1. 笛卡尔积与多表连接

1.1 笛卡尔积原理解释

笛卡尔积 描述的是多表连接组成一个新表的情况.

1.1.1 实例1:

假设集合A={a, b},集合B={0, 1, 2},则两个集合的笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。

1.1.2 实例2: (员工信息表 + 上级信息表)

员工信息表:
笛卡尔积与多表查询

上级信息表:
笛卡尔积与多表查询

备注: employee 表中 mgrno 是外键, 关联 manger 表中的 mgrno;

笛卡尔积: (8 * 3 = 24 行结果)
笛卡尔积与多表查询

1.2 SQL 中多表连接方式

每种数据库对于 多表连接实现存在较大的差异 , 故本文将分别通过 Oracle 和 MySQL 进行连接方式的对比和演示.

2. Oracle 实现的 demo

笛卡尔积与多表查询

备注: 演示使用的表, 是之前的 empolyee 和 manager 表;

2.1 连接方式

  1. 内连接

    • 内连接:

      • 内连接就是满足连接条件的结果集;
      • 语法: SELECT FROM emp INNER JOIN mgr ON {条件子句};*
    • 特例: 等值连接(也称为: 全值连接)

      • 等值连接是内连接的一种特例, 在 ON 条件子句中, 应当写成: 主表的主键与从表的相关键相等;
      • 语法: SELECT FROM emp INNER JOIN mgr ON emp.mgrno = mgr.mgrno;*
  2. 外连接

    • 左外连接:
      • 左外连接, 就是在等值连接的基础上, 加上左表中未被匹配的数据
      • 语法: SELECT FROM emp LEFT [OUTER] JOIN mgr ON {条件子句}; – [OUTER] 是可以省略的*
    • 右外连接:
      • 右外连接, 就是在等值连接的基础上, 加上右表中未被匹配的数据
      • 语法: SELECT FROM emp RIGHT [OUTER] JOIN mgr ON {条件子句}; – [OUTER] 是可以省略的*
    • 全外连接:
      • 全外连接, 就是在等值连接的基础上, 加上左表和右表中未被匹配的数据
      • 语法: SELECT FROM emp FULL [OUTER] JOIN mgr ON {条件子句}; – [OUTER] 是可以省略的*

2.2 Oracle 演示四种连接方式

使用 employee 和 manager 两张表, 进行演示.

注意:
1. 本实例中, 在 ON 子句中, 条件都是: 主表外键 = 从表关联键(一般也是从表主键); 当然也可以自定义条件;
2. 必须要有 ON 子句

2.2.1 内连接

-- 必须要有 ON 子句, 条件语句自定义;
-- 比如, 可以写: ON 1=1; 即, 返回所有内连接数据
SELECT * 
FROM emp INNER JOIN mgr 
ON 1=1; 

笛卡尔积与多表查询

2.2.2 等值连接(全值连接)

-- ON 子句必须写成: 主表的外键 = 从表的关联键(一般是从表的主键)
-- 如: emp 表的 mgr 外键 = mgr 表的 mgrno 主键
SELECT * 
FROM emp INNER JOIN mgr 
ON emp.mgr = mgr.mgrno; 

笛卡尔积与多表查询

2.2.3 左外连接

-- 此时, mgr 中有一行数据不满足 ON 子句条件, 但是依然要显示;
SELECT * 
FROM mgr OUTER JOIN emp 
ON emp.mgr = mgr.mgrno; 

笛卡尔积与多表查询

2.2.4 右外连接

SELECT * 
FROM emp RIGHT JOIN mgr 
ON emp.mgr = mgr.mgrno; 

2.2.5 全值连接

SELECT * 
FROM emp FULL JOIN mgr 
ON emp.mgr = mgr.mgrno; 

3. MySQL 实现的 demo

Studying… …

4. 总结

4.1 Oracle 中

在 Oracle 当中, 可以简单记忆成: 所有方式的连接都是:
1. 先通过笛卡尔集生成一张虚拟表, 这张虚拟表的行数是: tableA_rows * tableB_rows;
2. 接下来, 通过 ON 条件子句进行条件筛选;

但是, 需要注意:
1. 所有连接, 必须要有 ON 条件子句;
2. 全值连接, ON 子句必须写成: 主表外键=从表关联键;
3. 左外连接, 若是左表没有符合 ON 子句条件, 也会显示;
4. 右外连接, 同理;
5. 全外连接, 若是左表和右表没有符合, 都会显示;

4.2 MySQL 中

TODO… …