一、概述
数据库设计时,根据业务、模块的相互联系,数据库的表之间叶存在着各种各样的联系,他们的关系可以是:
 1)一对多(多对一)
 2)多对多
 3)一对一

二、 多表关系
 1)一对多(多对一)
  在多的一方建立外键,指向一的主键。
 2)多对多
  建立中间表,中间表至少包含两个外键,分别关联两个主键。
 3)一对一
  在任意一方加入外键,关联到另一方的主键,并且设置外键为唯一(UNIQUE)

三、笛卡尔积现象

select * from t1,t2; (t1、t2表示表1、表2)
  使用以上方式会查出t1、t2的所有组合情况(而一般多表查询是需要消除这种无效的笛卡尔积)
 可加上where条件消除:
  select * from t1,t2 where t1.id = t2.id;

四、多表查询分类

  1. 连接查询
    内连接:查询t1、t2的交集部分数据。
      隐式内连接:
      select 字段列表 from 表1,表2 where 条件 …;
      显式内连接:
      select 字段列表 from 表1 [inner] join 表2 on 连接条件 …;
    外连接:
      左外连接:查询左表所有数据,以及两张表的交集部分数据。
      select 字段列表 from 表1 left [outer] join 表2 on 条件;
    右外连接:查询右表所有数据,以及两张表的交集部分数据。
      select 字段列表 from 表1 right [outer] join 表2 on 条件;
    自连接:当前表与自身的连接查询,自连接必须使用表别名,要求两个关系表中进行比较的必须是相同的属性列。
      select 字段列表 from 表1 别名1 join 表2 别名2 on 条件 …;
  2. 联合查询
    对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集。
    注意:查询结果集列数、类型需要一样才能合并,[all]参数不去重,不带[all]去重。
select 字段列表 from 表1 ...
	union [all]
	select 字段列表 from 表2 ...;
  1. 子查询
    子查询也叫嵌套查询。
    语法:
    select * from t1 where cloumn1 = (select cloumn1 from t2);
    子查询外部语句可以是insert/update/delete/select中任意一个。
    按结果不同可以分为:
     ①标量子查询(子查询结果为单个)
     ②列子查询(子查询结果为一列,可以是多行)
     ③行子查询(子查询结果为一行)
     ④表子查询(子查询结果为多行多列)
    按子查询位置,分为:where之后、from之后、select之后;
    1)标量子查询
      select * from t1 where xx_id = (select id from t2 where name = “人事部”)
      select * from t1 where age > (select age from t2 where stu_id = 001);
    2) 列子查询
     常用操作符:
      IN:在指定集合范围内,多选一。
      NOT IN:不在指定集合范围内。
      ANY:子查询返回列表中,有一个满足即可。
      SOME:与any等同,使用SOME的地方都可以使用ANY
      ALL:子查询返回列表的所有值都必须满足。
      根据ID查询:
       select * from emp where dept_id in (select id from dept where name = “人事部” or “财务部”)
      比所有都高:
       select * from emp where salary > all (select salary from emp where dept_id = (select id from dept where name = “财务部”))
      比任意一人都高,some效果一样:
       select * from emp where salary > any (select salary from emp where dept_id = (select id from dept where name = “财务部”))
    3) 行子查询
       select * from emp where (salary,managerid) = (select salary,managerid from emp where name = “小美”)
    4) 表子查询
      查询职位、薪资相同的案例:
       select * from emp where (job,salary) in (select job,salary from emp where name =“zhangsan” or name =“lisi”)
      子查询用在from之后:
       select e.*,d.* from (select * from emp where entrydata > ‘2021-01-01’) e left join dept d on e.dept_id = d.id;