侧边栏壁纸
博主头像
爱探索

行动起来,活在当下

  • 累计撰写 43 篇文章
  • 累计创建 12 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

mysql-表关系操作

jelly
2024-07-31 / 0 评论 / 0 点赞 / 30 阅读 / 0 字

表关系操作

  1. 一对一
  2. 一对多或多对一
  3. 多对多

一、一对一关系

两个表中字段关系是一一对应的。例如:人和身份证。一般在数据库中如果两个表是一一对应 那么可以考虑将两张表合成一个表

二、 一对多(多对一)

1. 创建

示例:班级和学生,一个班级对应多个学生,一个学生对应一个班级

在实现的时候一般使用外键 实现

示例代码SQL:


-- 创建班级表





# 多表查询练习

-- 创建表 班级表
CREATE TABLE class (
    cid INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(10);
)

-- 创建课目

CREATE TABLE course(
    cid INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20)
);

-- 创建学生表
CREATE TABLE student(
    sid INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(10),
    sex CHAR(1),
    age INT,
    class_id INT,
    -- constraint [外键名称] foreign key ([外键列名称]) references [主表名称]([ 主表列名称 ])
    CONSTRAINT foreign_class_id FOREIGN KEY (class_id) REFERENCES class(cid)
);

-- 创建专业与学生关系表

CREATE TABLE correlation_student_course(
    student_id INT,
    course_id INT,
    CONSTRAINT foreign_student_id FOREIGN KEY (student_id) REFERENCES student(sid),
    CONSTRAINT foreign_course_id FOREIGN KEY (course_id) REFERENCES course(cid)
);

-- 插入年纪数据

INSERT  INTO class(name) values 
(
    '大一'
),
(
    '大二'
),
(
    '大三'
)
,(
    '大四'
);
/*
+-----+--------+
| cid | name   |
+-----+--------+
|   1 | 大一   |
|   2 | 大二   |
|   3 | 大三   |
|   4 | 大四   |
+-----+--------+
*/



-- 插入专业数据

INSERT course(name) values('C语言'),('数据结构'),('计算机组成原理'),('高数一');
 
 /*
+-----+-----------------------+
| cid | name                  |
+-----+-----------------------+
|   1 | C语言                 |
|   2 | 数据结构              |
|   3 | 计算机组成原理        |
|   4 | 高数一                |
+-----+-----------------------+
*/

-- 插入学生

INSERT student(name,sex,age,class_id) values
(
    '张三','男' ,18,(SELECT cid FROM  class WHERE name='大一')
),(
    '王五','男' ,21,(SELECT cid FROM  class WHERE name='大一')
),
(
    '赵四','男' ,21,(SELECT cid FROM  class WHERE name='大二')
),(
    '钟无艳','女' ,22,(SELECT cid FROM  class WHERE name='大三') 
),(
    '黄蓉','女' ,18,(SELECT cid FROM  class WHERE name='大一')
),(
    '郭靖','女' ,24,(SELECT cid FROM  class WHERE name='大四')
),(
    '小龙女','女' ,24,(SELECT cid FROM  class WHERE name='大四') 
);


--追加学号
update student set student_number='21001' where name='张三';
update student set student_number='21002' where name='王五';
update student set student_number='21003' where name='赵四';
update student set student_number='21004' where name='钟无艳';
update student set student_number='21005' where name='黄蓉';
update student set student_number='21006' where name='郭靖';
update student set student_number='21007' where name='小龙女';

alter table student modify student_number char(5) not null unique; 

-- 修改外键关联关系

ALTER TABLE STUDENT 

-- 插入关系表数据
-- 同理插入多个数据
INSERT INTO correlation_student_course(
    student_id,course_id
)
VALUES
(
    (SELECT sid FROM student WHERE student_number='21007') , -- 注意这里需要使用括号括起来
    (SELECT cid FROM course WHERE name ='计算机组成原理')
);



2. 查询

查询以上表为例


student 表中数据
+-----+-----------+------+------+----------+----------------+
| sid | name      | sex  | age  | class_id | student_number |
+-----+-----------+------+------+----------+----------------+
|   2 | 张三      | 男   |   18 |        9 | 21001          |
|   3 | 王五      | 男   |   21 |        9 | 21002          |
|   4 | 赵四      | 男   |   21 |       10 | 21003          |
|   5 | 钟无艳    | 女   |   22 |       11 | 21004          |
|   6 | 黄蓉      | 女   |   18 |        9 | 21005          |
|   7 | 郭靖      | 女   |   24 |       12 | 21006          |
|   8 | 小龙女    | 女   |   24 |       12 | 21007          |
+-----+-----------+------+------+----------+----------------+

course 表中数据
+-----+-----------------------+
| cid | name                  |
+-----+-----------------------+
|   1 | C语言                 |
|   2 | 数据结构              |
|   3 | 计算机组成原理        |
|   4 | 高数一                |
+-----+-----------------------+

class 表中数据
+-----+--------+
| cid | name   |
+-----+--------+
|   9 | 大一   |
|  10 | 大二   |
|  11 | 大三   |
|  12 | 大四   |
+-----+--------+

correlation_student_course 表中数据

+------------+-----------+
| student_id | COURSE_id |
+------------+-----------+
|          2 |         3 |
|          2 |         4 |
|          4 |         1 |
|          4 |         2 |
|          5 |         4 |
|          6 |         4 |
|          3 |         4 |
|          3 |         1 |
|          3 |         2 |
|          7 |         2 |
|          7 |         1 |
|          8 |         1 |
|          8 |         3 |
+------------+-----------+

1>笛卡尔积。

如果直接查询不加限制条件查出来的结果将是笛卡尔积,即两个表的乘积

示例:


SELECT * FROM student ,class;

+-----+-----------+------+------+----------+----------------+-----+--------+
|   2 | 张三      | 男   |   18 |        9 | 21001          |  12 | 大四   |
|   2 | 张三      | 男   |   18 |        9 | 21001          |  11 | 大三   |
|   2 | 张三      | 男   |   18 |        9 | 21001          |  10 | 大二   |
|   2 | 张三      | 男   |   18 |        9 | 21001          |   9 | 大一   |
|   3 | 王五      | 男   |   21 |        9 | 21002          |  12 | 大四   |
|   3 | 王五      | 男   |   21 |        9 | 21002          |  11 | 大三   |
|   3 | 王五      | 男   |   21 |        9 | 21002          |  10 | 大二   |
|   3 | 王五      | 男   |   21 |        9 | 21002          |   9 | 大一   |
|   4 | 赵四      | 男   |   21 |       10 | 21003          |  12 | 大四   |
|   4 | 赵四      | 男   |   21 |       10 | 21003          |  11 | 大三   |
|   4 | 赵四      | 男   |   21 |       10 | 21003          |  10 | 大二   |
|   4 | 赵四      | 男   |   21 |       10 | 21003          |   9 | 大一   |
|   5 | 钟无艳    | 女   |   22 |       11 | 21004          |  12 | 大四   |
|   5 | 钟无艳    | 女   |   22 |       11 | 21004          |  11 | 大三   |
|   5 | 钟无艳    | 女   |   22 |       11 | 21004          |  10 | 大二   |
|   5 | 钟无艳    | 女   |   22 |       11 | 21004          |   9 | 大一   |
|   6 | 黄蓉      | 女   |   18 |        9 | 21005          |  12 | 大四   |
|   6 | 黄蓉      | 女   |   18 |        9 | 21005          |  11 | 大三   |
|   6 | 黄蓉      | 女   |   18 |        9 | 21005          |  10 | 大二   |
|   6 | 黄蓉      | 女   |   18 |        9 | 21005          |   9 | 大一   |
|   7 | 郭靖      | 女   |   24 |       12 | 21006          |  12 | 大四   |
|   7 | 郭靖      | 女   |   24 |       12 | 21006          |  11 | 大三   |
|   7 | 郭靖      | 女   |   24 |       12 | 21006          |  10 | 大二   |
|   7 | 郭靖      | 女   |   24 |       12 | 21006          |   9 | 大一   |
|   8 | 小龙女    | 女   |   24 |       12 | 21007          |  12 | 大四   |
|   8 | 小龙女    | 女   |   24 |       12 | 21007          |  11 | 大三   |
|   8 | 小龙女    | 女   |   24 |       12 | 21007          |  10 | 大二   |
|   8 | 小龙女    | 女   |   24 |       12 | 21007          |   9 | 大一   |
+-----+-----------+------+------+----------+----------------+-----+--------+

--这样的查询是没有什么意义的

2>内联查询

一般求的是两个表的交集。

显示内联接语法
select [字段列表] from [表名1] inner join[ 表名2] on [条件] --inner 可选字段

  1. 隐式内连接:使用where条件消除无用数据。

    
    SELECT * FROM student,class WHERE student.class_id=class.cid;
    
    +-----+-----------+------+------+----------+----------------+-----+--------+
    | sid | name      | sex  | age  | class_id | student_number | cid | name   |
    +-----+-----------+------+------+----------+----------------+-----+--------+
    |   2 | 张三      | 男   |   18 |        9 | 21001          |   9 | 大一   |
    |   3 | 王五      | 男   |   21 |        9 | 21002          |   9 | 大一   |
    |   6 | 黄蓉      | 女   |   18 |        9 | 21005          |   9 | 大一   |
    |   4 | 赵四      | 男   |   21 |       10 | 21003          |  10 | 大二   |
    |   5 | 钟无艳    | 女   |   22 |       11 | 21004          |  11 | 大三   |
    |   7 | 郭靖      | 女   |   24 |       12 | 21006          |  12 | 大四   |
    |   8 | 小龙女    | 女   |   24 |       12 | 21007          |  12 | 大四   |
    +-----+-----------+------+------+----------+----------------+-----+--------+
    
    
  2. 显示内连接

    -- select [字段列表] from [表名1] inner join [表名2] on [条件]
    
    SELECT s.name 姓名,s.sex 性别,c.name 年级 FROM student s INNER JOIN class c on s.class_id=c.cid;
    
    +-----------+--------+--------+
    | 姓名      | 性别   | 年级   |
    +-----------+--------+--------+
    | 张三      | 男     | 大一   |
    | 王五      | 男     | 大一   |
    | 黄蓉      | 女     | 大一   |
    | 赵四      | 男     | 大二   |
    | 钟无艳    | 女     | 大三   |
    | 郭靖      | 女     | 大四   |
    | 小龙女    | 女     | 大四   |
    +-----------+--------+--------+
    
    

2>外连接查询

  • 左连接
    select [字段列表] from [表1] left outer join [表2] on [条件];-- outer可以不写
    表一的全集与表一表二的交集的和

  • select [字段列表] from [表1] right outer join [表2] on [条件];-- -- outer可以不写
    表二的全集与表一表二的交集的和


SELECT 
    s.student_number 学号, s.name 姓名,c.name 年级
FROM
student s 
LEFT OUTER JOIN 
class c 
ON s.class_id=c.cid;

+--------+-----------+--------+
| 学号   | 姓名      | 年级   |
+--------+-----------+--------+
| 21001  | 张三      | 大一   |
| 21002  | 王五      | 大一   |
| 21003  | 赵四      | 大二   |
| 21004  | 钟无艳    | 大三   |
| 21005  | 黄蓉      | 大一   |
| 21006  | 郭靖      | 大四   |
| 21007  | 小龙女    | 大四   |
+--------+-----------+--------+

-- 右连接
SELECT 
     s.student_number 学号, s.name 姓名,c.name 年级
FROM 
    class c 
RIGHT OUTER JOIN
    student s
ON
c.cid=s.class_id;

+--------+-----------+--------+
| 学号   | 姓名      | 年级   |
+--------+-----------+--------+
| 21001  | 张三      | 大一   |
| 21002  | 王五      | 大一   |
| 21003  | 赵四      | 大二   |
| 21004  | 钟无艳    | 大三   |
| 21005  | 黄蓉      | 大一   |
| 21006  | 郭靖      | 大四   |
| 21007  | 小龙女    | 大四   |
+--------+-----------+--------+

3>子查询

查询中嵌套查询,称嵌套查询为子查询。

子查询不同情况:

  1. 子查询的结果是单行单列的]

    -- 子查询可以作为条件,使用运算符去判断。 运算符: > >= < <= =
    1. 查询年龄大于平均年龄的人的姓名年龄
    SELECT  name,age FROM student WHERE age>(SELECT AVG(age) FROM student);
    +-----------+------+
    | name      | age  |
    +-----------+------+
    | 钟无艳    |   22 |
    | 郭靖      |   24 |
    | 小龙女    |   24 |
    +-----------+------+
    
  2. 子查询的结果是多行单列的

    -- 子查询可以作为条件,使用运算符in来判断
    -- 查询有C语言课程,与数据结构课程的人的信息
    SELECT 
       * 
    FROM 
        student 
    WHERE 
    
    sid IN
        (
        SELECT 
            student_id
        FROM 
            correlation_student_course
        WHERE
            course_id 
        IN
            (
            SELECT 
                cid 
            FROM 
                course
            WHERE name= "C语言" OR name='数据结构'
            )
        );
    
    +-----+-----------+------+------+----------+----------------+
    | sid | name      | sex  | age  | class_id | student_number |
    +-----+-----------+------+------+----------+----------------+
    |   3 | 王五      | 男   |   21 |        9 | 21002          |
    |   4 | 赵四      | 男   |   21 |       10 | 21003          |
    |   7 | 郭靖      | 女   |   24 |       12 | 21006          |
    |   8 | 小龙女    | 女   |   24 |       12 | 21007          |
    +-----+-----------+------+------+----------+----------------+
    
    
  3. 子查询的结果是多行多列的

    --  子查询可以作为一张虚拟表参与查询
    -- 查询 大于20岁 对学生信息
    
    SELECT 
        s.name 姓名,s.sex 性别,s.age 年龄,c.name 年级
    FROM 
        class c,
        (
        SELECT
            *
        FROM
            student
        WHERE 
            age>20
        ) s
    WHERE
        c.cid=s.class_id;
    
    +-----------+--------+--------+--------+
    | 姓名      | 性别   | 年龄   | 年级   |
    +-----------+--------+--------+--------+
    | 王五      | 男     |     21 | 大一   |
    | 赵四      | 男     |     21 | 大二   |
    | 钟无艳    | 女     |     22 | 大三   |
    | 郭靖      | 女     |     24 | 大四   |
    | 小龙女    | 女     |     24 | 大四   |
    +-----------+--------+--------+--------+
    
0

评论区