• MySQL(五) 多表查询


    5 多表操作

      5.1. 外键

      引用另一个表中的一列或者多列,被引用的列应该具有主键约束或者非空约束

      搭建环境,在数据库test中创建主表class:

    CREATE TABLE class(
        cid INT(4) NOT NULL PRIMARY KEY,
        cname VARCHAR(10)
    );

      5.1.1 添加外键约束

      (1) 在创建表的同时为表添加外键(在从表中添加SQL语句)

      格式:CONSTRAINT 自定义外键名 FOREIGN KEY (从表引用字段名)

            REFERENCES 主表名 (主表被引用字段名)

    CREATE TABLE student(
        sid INT(4),
        sname VARCHAR(10),
        cid INT(4),
        CONSTRAINT FK_ID FOREIGN KEY (cid) REFERENCES class (cid)
    );

      

      (2) 为已存在的表添加外键

      搭建环境,在数据库test下创建数据表pupil(先删除数据表student)

    CREATE TABLE pupil(
        sid INT(4),
        sname VARCHAR(10),
        cid INT(4)
    );

      格式:ALTER TABLE 从表名 ADD CONSTRAINT 自定义外键名

            FOREIGN KEY (从表引用字段名)

            REFERENCES 主表名 (主表被引用字段名)

    ALTER TABLE pupil ADD CONSTRAINT FK_ID
    FOREIGN KEY (cid)
    REFERENCES class (cid);

      

      5.1.2 删除外键约束

      格式:ALTER TABLE 从表名

            DROP FOREIGN KEY 外键名

    ALTER TABLE pupil
    DROP FOREIGN KEY FK_ID;      

      5.2. 操作关联表

      5.2.1 关联关系

      一对多(班级与学生):将外键建在多的一方。

      多对多(课程与学生):定义一张中间表(连接表),该表会存在两个外键,分别参照课程表和学生表

      一对一(人与身份证):从主从关系入手,从表需要主表的存在才有意义

      5.2.2 添加数据

      给从表添加数据时,它引用的字段必须为主表中被引用字段的值

      5.2.3 删除数据

      在具有关联关系的表中删除数据时,一定要先删除从表中的数据,然后再删除主表中的数据,否则会报错

      5.3. 连接查询

      下面的两张表通过相同意义的字段模拟外键约束,并没有真正的外键约束,但其特点和外键是一样的,可以通过这些字段对不同的表进行连接查询

      搭建查询环境,在数据库test下创建数据表department和employee

    CREATE TABLE department(
        did INT(4) NOT NULL PRIMARY KEY,
        dname VARCHAR(20)
    );
    CREATE TABLE employee(
        id INT(4) NOT NULL PRIMARY KEY,
        name VARCHAR(10),
        age INT(2),
        did INT(4) NOT NULL
    );

      在两个表中插入相关数据

    INSERT INTO department 
    VALUES (1,'network'),(2,'media'),(3,'development'),(5,'personnel');

      

    INSERT INTO employee
    VALUES (1,'Zhou',20,1),(2,'Will',22,1),(3,'Marry',20,2),(4,'Jin',20,4);

      

      5.3.1 交叉连接(笛卡尔积)

      格式:SELECT 字段名 FROM 主表CROSS JOIN 从表;

    SELECT * FROM department CROSS JOIN employee;

      相当于:

    SELECT * FROM department,employee;

      

      5.3.2 内连接(自然连接)

      格式:SELECT 字段名 FROM 主表

            [INNER] JOIN 从表

            ON 主表.关系字段=从表.关系字段

    SELECT department.dname,employee.name 
    FROM department INNER JOIN employee
    ON department.did=employee.did;

      相当于:

    SELECT department.dname,employee.name 
    FROM department,employee
    WHERE department.did=employee.did;

      

      5.3.3 外连接

      (1) 左连接:以左表为准,去右表找数据,找不到,用null补齐

      格式:SELECT 字段名 FROM 左表

            LEFT JOIN 右表

            ON 左表.关系字段=右表.关系字段

    SELECT department.dname,employee.name 
    FROM department LEFT JOIN employee
    ON department.did=employee.did;

      

      (2) 右连接:以右表为准,去左表找数据,找不到,用null补齐

      格式:SELECT 字段名 FROM 左表

            RIGHT JOIN 右表

            ON 左表.关系字段=右表.关系字段

    SELECT department.dname,employee.name 
    FROM department RIGHT JOIN employee
    ON department.did=employee.did;

      

      注意:在左连接中互换左右表的位置,同样可以得到右连接的效果

      (3) 全连接(FULL JOIN):MySQL不支持,可以通过左连接UNION右连接得到

      5.3.4 子查询

      (1) 带IN关键字的子查询

      使用IN关键字进行子查询时,内层查询语句仅返回一个数据列,这个数据列中的值将供外层查询语句进行比较操作

      例:查询存在20岁的员工的部门

    SELECT dname FROM department
    WHERE did IN
    (SELECT did FROM employee WHERE age=20);

      

      (2) 带EXISTS关键字的子查询

      EXISTS关键字后面的参数可以是任意一个子查询,这个子查询的作用相当于测试,它不会产生任何数据,只返回TRUE或FALSE,当返回值为TRUE时,外层查询才会执行。

      例:查询是否存在年龄大于21岁的员工,如果存在,则查询department表中所有的记录

    SELECT dname FROM department
    WHERE EXISTS
    (SELECT did FROM employee WHERE age>21);

      

      (3) 带ANY关键字的查询

      ANY关键字表示满足其中任意一个条件,它允许创建一个表达式对子查询的返回值列表进行比较,只要满足内层子查询的任意一个比较条件,就返回一个结果作为外层查询条件

    SELECT * FROM department 
    WHERE did>ANY (SELECT did FROM employee);

      

      (4) 带ALL关键字的子查询

      ALL关键字表示满足所有的条件,子查询返回的结果需同时满足所有的内层查询条件

    SELECT * FROM department
    WHERE did>ALL (SELECT did FROM employee);

      

      (5) 带比较运算符的子查询

    SELECT * FROM department
    WHERE did=(SELECT did FROM employee WHERE name='Marry');

      

  • 相关阅读:
    关于使用_bstr_t的一个坑
    ubuntu下使用sublime text进行C编程开发尝鲜
    [转]在ubuntu下安装sublime text
    [转] COM编程总结
    [转]wcout输出中文却不显示出来
    理解抽象类与接口
    软件设计原则[总结]
    [转] 在图标库中,找到合适的图标 ico
    [转]单播、多播(组播)、广播简介
    NUC970开发资源
  • 原文地址:https://www.cnblogs.com/tcxpz/p/10013079.html
Copyright © 2020-2023  润新知