SQL007 数据库整理笔记 (7) 多表查询 (上)

103 阅读4分钟

9. 多表查询

9.1 表与表之间的关系

  • 实际开发中,一个项目通常需要很多张表才能完成。例如:一个商城项目就需要分类表(category)、 商品表(products)、订单表(orders)等多张表。
  • 一对一的关系

    • 一对一的关系很少见,如一个身份证号对应一个人,这种关系不需要多表,一张表就可以了。
  • 一对多的关系

    • 一对多的关系比较常中见,如一个班级有很多学习,一个部分有很多员工。
    • 这种情况下,一般会建立两张表,表之间使用一个公共子段来连接。
  • 多对多的关系

    • 多对多的关系也行常见,如多个老师对多个学生。学生和课程也是多个学生对多个课程。
    • 这种情况下,一般会两两张表之间建立一个中间表,中间表与两张这间采用一对多的关系来建立连接。

多表连接不宜过多, 如果表中数据比较多,可以尽量避免3张以上的多表连接。

9.2 多表连接与笛卡尔积

  • 不同的数据放入不同的表中,在查询的时候,数据可能来自多张表,这就是多表连接。
  • 语法: select 表1.字段, 表2.字段 .. from 表1, 表2
-- 查询员工信息 (first_name 和 部门ID 和 部门名称)
SQL> SELECT s_emp.first_name, s_emp.dept_id, s_dept.name AS dept_name FROM s_emp, s_dept;
  • 在这个例子中,我们查询出来的记录条数比表中的记录还,这是因为两张表之间查询记录时逐条匹配,形成了笛卡尔积。

  • 在多表查询中一定要消除笛卡尔积。

  • 使用连接条件可以避免笛卡尔积

    • 语法: select 表1.字段, 表2.字段 .. from 表1, 表2 连接条件

9.3 内连接

9.3.1 隐式内连接

  • 使用 where 连接条件来连接多个表,这种方式就是隐式内连接
  • 语法: select 表1.字段1, 表1.字段2, ... 表n.字段n from 表1, ..., 表n where 连接条件;
  • 如果查询的表的字段没有重复,表名.可以省略

  • 为了简化SQL结构语句,可以使用别名

    • 表一旦使用了别名,在语句中只能使用别名,不能再使用原来的名称。
    • 注意: 表的别名使用空格,ORACLE中不能使用as关键字。
  • 多表连接必须要有连接条件 , N个表,必须要有N-1个连接条件。

    • select 表1别名.字段1, 表1别名.字段2, ... 表n别名.字段n from 表1 表1别名, ..., 表n 表n别名 where 连接条件;
-- 查询员工信息 (first_name 和 部门ID 和 部门名称)
-- mysql和oracle都可以
SQL> SELECT e.first_name, d.id, d.name FROM s_emp  e, s_dept  d
    WHERE e.dept_id = d.id;
    
-- MYSQL
SQL> SELECT e.first_name, d.id, d.name FROM s_emp AS e, s_dept AS d
    WHERE e.dept_id = d.id;

9.3.2 显式内连接

  • 使用from a表 [inner] join b表 on 连接条件

    • inner可以省略
-- 把每个部门名和对应的地区名显示出来
SQL> SELECT d.id, r.name FROM s_dept d INNER JOIN s_region r ON d.region_id = r.id;

9.3.3 练习

  • 使用两种内连接方式查询如下信息: 查询员工表、部门表、区域名(region)取出 last_name, 部门名称、区域名称
-- 查询员工表、部门表、区域名(region)取出 last_name, 部门名称、区域名称

SQL> SELECT last_name, d.name dept_name , r.name region_name
                FROM s_emp e, s_dept d, s_region r
                    WHERE e.dept_id = d.id AND d.region_id = r.id;
                    
-- 显式内链接
SQL> SELECT last_name, d.name dept_name , r.name region_name
                FROM s_emp e JOIN s_dept d JOIN s_region r
                    ON e.dept_id = d.id AND d.region_id = r.id;

9.4 自连接

9.4 自连接

  • 内连接有三种方式

    • 等值连接 - 用等号做连接条件

    • 非等值连接 - 不用等号做连接条件,比如用大于号等。

      • 便如查询在某个范围内的值
    • 自连接 - 本表之间的连接(就一张表)

  • 自连接是逻辑上把一张表当成两张表来使用。
  • 自连接时,表名必须使用别名。

-- 练习:找出领导--找出员工的id, first_name, manager_id
SQL> SELECT id, first_name, manager_id FROM s_emp;
​
-- 列出员工与领导的信息
SQL> SELECT e.id, e.first_name, m.id, m.first_name FROM 
    s_emp e, s_emp m
        WHERE e.manager_id = m.id;
        
        
-- 保留领导的信息,并去除重复的
SQL> SELECT DISTINCT m.id, m.first_name FROM 
    s_emp e, s_emp m
        WHERE e.manager_id = m.id;

自连接是一个比较难理解的点,但是我们用后面学习的子查询一样可以达到这种效果。