MySQL表的增删改查进阶版

news2025/4/19 7:26:45

Mysql

  • 1、数据库的约束
    • 1.1约束类型
    • 1.2 NULL约束
    • 1.3 UNIQUE:唯一约束
    • 1.4 DEFAULT:默认值约束
    • 1.5 PRIMARY KEY:主键约束(重点)
    • 1.6 FOREIGN KEY:外键约束(重点)
  • 2.表的设计
    • 2.1一对一
    • 2.2一对多
    • 2.3多对多
  • 3.新增
  • 4.查询
    • 4.1聚合查询
      • 4.1.1聚合函数
      • 4.1.2GROUP BY 子句
      • 4.1.3HAVING
    • 4.2联合查询
      • 4.2.1内连接
      • 4.2.2外连接
      • 4.2.3自连接
      • 4.2.4子查询
      • 4.2.5合并查询

1、数据库的约束

1.1约束类型

什么是约束?
约束是数据库自动对数据进行合法性校验检查的一系列机制,目的是为了数据库中能避免被插入/修改一些非法的数据,数据库引入约束后执行效率会受影响,效率会降低很多

  • NOT NULL:知识某列不能存储NULL值
  • UNIQUE :保证某列的每行必须有唯一的值,unique会让后续插入/修改数据时都先触发一次查询操作,确定当前记录是否存在
  • DEFAULT:规定没有给列赋值时的默认值
  • PRIMARY KEY:NOT NULL和UNIQUE的结合,确保某列有唯一标识,有助于更快速地找到表中的一个特定的记录,一张表中只能有一个primary key
  • FOREIGN KEY:保证一个表中数据匹配另一个表中的值的参照完整性
  • CHECK:保证列中的值符合指定的条件

下面我们来进行逐一解释

1.2 NULL约束

创建表时,可以指定某列不为空

mysql> create table student
(id int not null,sn int,name varchar(20),qq_mail varchar(20));
-- 如果id列插入null类型的数据,则会报错
mysql> insert into student values(null,1,'lisi','ddd');
ERROR 1048 (23000): Column 'id' cannot be null

1.3 UNIQUE:唯一约束

指定sn列是唯一的,不重复的

mysql> create table student
(id int not null,sn int unique,name varchar(20),qq_mail varchar(20));
Query OK, 0 rows affected (0.02 sec)
-- 我们可以在以下代码看到,sn只能插入一次相同的值,重复插入会报错
mysql> insert into student values(1,1,'qqq','qqq');
Query OK, 1 row affected (0.01 sec)
mysql> insert into student values(1,1,'qqq','qqq');
ERROR 1062 (23000): Duplicate entry '1' for key 'sn'
mysql> 

1.4 DEFAULT:默认值约束

指定插入数据时,name列为空,则默认值为unkown

create table student
(id int not null,sn int unique,name varchar(20) default 'unkown',qq_mail varchar(20));
-- 在下列代码可以看到name列没被插入,系统自动补成unkown
mysql> insert into student(id ,sn,qq_mail) values(2,2,'qqq');
Query OK, 1 row affected (0.01 sec)
mysql> select * from student;
+----+------+--------+---------+
| id | sn   | name   | qq_mail |
+----+------+--------+---------+
|  2 |    2 | unkown | qqq     |
+----+------+--------+---------+
1 row in set (0.00 sec)

1.5 PRIMARY KEY:主键约束(重点)

指定id列为主键

mysql> create table student
(id int not null primary key,name varchar(20));
Query OK, 0 rows affected (0.01 sec)

如何保证主键唯一呢?
MySQL提供一种“自增主键”这样的机制,主键经常使用int/big int,我们插入数据的时候,不必手动指定主键值,由数据库服务器自己分配一个主键,从1开始,依次递增的分配主键的值

对于整数类型的主键,常搭配子增长auto_increment来使用,插入数据对应字段不给值时(null,这里写作null其实是交给数据库服务器自行分配),使用最大值+1(相当于使用了一个变量来保存当前表的ID最大值,后续分配自增主键都是根据这个最大值分配的,如果手动指定的id也会更新最大值)
自动分配也有一定的局限性,如果是单个MySQL没问题,如果是一个分布式系统有多个MySQL服务器构成的集群,这个时候自增主键就不行了

-- 主键是NOT NULL和UNIQUE的结合,可以不用NOT NULL
create table student1
(id int  primary key auto_increment,name varchar(20));
Query OK, 0 rows affected (0.01 sec)
-- 插入多条数据,不指定id,我们来看一下效果
mysql> insert into student1(name) values('qqq');  
mysql> insert into student1(name) values('qqq');
mysql> insert into student1(name) values('qqq');
mysql> insert into student1(name) values('qqq');
mysql> select * from student1;
+----+------+
| id | name |
+----+------+
|  1 | qqq  |
|  2 | qqq  |
|  3 | qqq  |
|  4 | qqq  |
+----+------+
4 rows in set (0.00 sec)

-- 当我们指定了一个id,自增主键会更新最大值,我们来看下效果
mysql> insert into student1 values(11,'qqq');
Query OK, 1 row affected (0.00 sec)

mysql> insert into student1(name) values('qqq');
Query OK, 1 row affected (0.00 sec)
mysql> select * from student1;
+----+------+
| id | name |
+----+------+
|  1 | qqq  |
|  2 | qqq  |
|  3 | qqq  |
|  4 | qqq  |
| 11 | qqq  |
| 12 | qqq  |
+----+------+
6 rows in set (0.00 sec)

分布式唯一id:=时间戳+主机编号/机房编号+随机因子
+指的是字符串拼接,不是算数相加

1.6 FOREIGN KEY:外键约束(重点)

外键用于关联其他表的主键或唯一键,描述了两个表之间的关联关系,只有用到的才受约束。
语法:

foreign key (子表的列) reference 主表();

进一步解释子表的列表示当前哪个表的哪个列被约束,主表(列)表示数据是被谁约束,也就是说,子表的列要出自于主表后括号中的那一列references表示当前这个表的这一列中的数据应该是出自另一个表的哪一列

  • 例:classes表中的数据约束了student表中的数据,classes称为父表(约束别人的表),student称为子表(被人约束的表)

创建班级表classes,id为主键:

mysql> create table classes
(id int primary key auto_increment,
name varchar(20),
`desc` varchar(100));

创建学生表student,一个学生对应一个班级,一个班级对应多个学生,使用id为主键,classes_id为外键,关联班级表id

mysql> create table student
(id int primary key auto_increment,
sn int unique,
name varchar(20) default 'unkown',
qq_mail varchar(20),
classes_id int,
foreign key (classes_id) references classes(id));
Query OK, 0 rows affected (0.02 sec)

-- 我们可以看到如下代码
mysql> insert into classes(name,`desc`) values('qqq','aaa');
Query OK, 1 row affected (0.00 sec)
mysql> select * from classes;
+----+------+------+
| id | name | desc |
+----+------+------+
|  1 | qqq  | aaa  |
+----+------+------+
1 row in set (0.00 sec)
-- 在这里我们发现把一个学生的班级设置为2会错误,因为classes表中没有id为2这个班级
mysql> insert into student(name,classes_id) values('qqq',2);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`db_test`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`classes_id`) REFERENCES `classes` (`id`))
-- 班级设置为1则正确
mysql> insert into student(name,classes_id) values('qqq',1);
Query OK, 1 row affected (0.00 sec)
mysql> select * from student;
+----+------+------+---------+------------+
| id | sn   | name | qq_mail | classes_id |
+----+------+------+---------+------------+
|  2 | NULL | qqq  | NULL    |          1 |
+----+------+------+---------+------------+
1 row in set (0.00 sec)

要对父表进行修改/删除操作,如果当前被修改/删除的值已经被子表引用了,这样的操作会失败,外键约束始终要保持子表中的数据要在对应的父表的列中存在,此时万一把父表这条数据删除了,就打破刚才的约束了,所以删除会报错

若想删除关联的表,只能先删除子表,再删父表

2.表的设计

根据实际的需求场景,明确当前要创建几个表,每个表啥样子,这些表之间是否存在一定联系

一般来说,每个实体都需要安排一个表,表的列就对应到实体的各个属性

  • 三大范式

2.1一对一

一个学生只能拥有***一个***账号
一个账号只能被***一个***学生拥有
在这里插入图片描述

2.2一对多

一个学生只能在***一个***班级中
一个班级可以包括***多个***学生
在这里插入图片描述

2.3多对多

一个学生可以选择***多门***课程
一门课程也可以包含***多个***学生

3.新增

把查询语句的查询结果作为插入的数值
语法:

insert into 表名 select * from 表名;
  • 例:设计一张用户表,把已有的学生数据复制进来
mysql> insert into test_user(name) select name from student1;
Query OK, 6 rows affected (0.01 sec)
Records: 6  Duplicates: 0  Warnings: 0
-- 我们可以看到,学生姓名已经被成功的复制进来
mysql> select * from test_user;
+----+------+------+
| id | name | age  |
+----+------+------+
|  1 | qqq  | NULL |
|  2 | aaa  | NULL |
|  3 | bbb  | NULL |
|  4 | ccc  | NULL |
|  5 | ddd  | NULL |
|  6 | eee  | NULL |
+----+------+------+
6 rows in set (0.00 sec)

4.查询

4.1聚合查询

表达式查询是针对列和列之间进行运算的,
聚合查询是相当于行和行之间进行运算的。

4.1.1聚合函数

SQL中提供了聚合函数,常见的统计总数,计算平均值等操作,可以使用聚合函数来实现,以下是常见的聚合函数:

函数说明
COUNT(expr)返回查询到的数据的数量,查询出来结果是集的行数
SUM(expr)返回查询到的数据的总和,只能针对数字,把这一列的若干行求和,算术运算
AVG(expr)返回查询到的数据的平均值
MAX(expr)返回查询到的数据的最大值
MIN(expr)返回查询到的数据的最小值
  • COUNT
-- 插入测试数据
mysql> insert into test_user (name) values('张三'),('李四'),('王五'),('赵六');
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0
-- 查询(用*查询不可进行去重,NULL也算进去)
mysql> select count(*) from test_user;
+----------+
| count(*) |
+----------+
|        4 |
+----------+
1 row in set (0.00 sec)
mysql> select count(0) from test_user;
+----------+
| count(0) |
+----------+
|        4 |
+----------+
1 row in set (0.01 sec)
-- 再插入几组年龄数据,姓名为空
mysql> insert into test_user (age) values(10),(12),(13);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
-- 我们先查询一下
mysql> select * from test_user;
+----+--------+------+
| id | name   | age  |
+----+--------+------+
|  8 | 张三   | NULL |
|  9 | 李四   | NULL |
| 10 | 王五   | NULL |
| 11 | 赵六   | NULL |
| 12 | NULL   |   10 |
| 13 | NULL   |   12 |
| 14 | NULL   |   13 |
+----+--------+------+
7 rows in set (0.00 sec)
-- 统计班级收集的年龄信息有多少个,年龄为NULL不会计入结果,也可进行去重
mysql> select count(age) from test_user;
+------------+
| count(age) |
+------------+
|          3 |
+------------+
1 row in set (0.00 sec)
  • SUM
mysql> select * from exam_result;
+------+-----------+---------+------+---------+
| id   | name      | chinese | math | english |
+------+-----------+---------+------+---------+
|    1 | 唐三藏    |    67.0 | 98.0 |    56.0 |
|    2 | 孙悟空    |    87.5 | 78.0 |    77.0 |
|    3 | 猪悟能    |    88.0 | 98.5 |    90.0 |
|    4 | 曹孟德    |    82.0 | 84.0 |    67.0 |
|    5 | 刘玄德    |    55.5 | 85.0 |    45.0 |
|    6 | 孙权      |    70.0 | 73.0 |    78.5 |
|    7 | 宋公明    |    75.0 | 65.0 |    30.0 |
+------+-----------+---------+------+---------+
7 rows in set (0.00 sec)

mysql> select sum(chinese) from exam_result;
+--------------+
| sum(chinese) |
+--------------+
|        525.0 |
+--------------+
1 row in set (0.00 sec)

sum函数中也可以使用表达式,先把对应列相加,得到的临时表再把这个临时表的结果进行相加,举例如下

mysql> select sum(chinese + math) from exam_result;
+---------------------+
| sum(chinese + math) |
+---------------------+
|              1106.5 |
+---------------------+
1 row in set (0.00 sec)
  • AVG
mysql> select avg(chinese+english+ math) as 平均总分 from exam_result;
+--------------+
| 平均总分     |
+--------------+
|    221.42857 |
+--------------+
1 row in set (0.00 sec)
  • MAX
mysql> select max(english) as 英语最高分 from exam_result;
+-----------------+
| 英语最高分      |
+-----------------+
|            90.0 |
+-----------------+
1 row in set (0.00 sec)
  • MIN
mysql> select min(math) as 数学最低分 from exam_result;
+-----------------+
| 数学最低分      |
+-----------------+
|            65.0 |
+-----------------+
1 row in set (0.00 sec)

4.1.2GROUP BY 子句

针对指定列进行分组,把这一列中值相同的行,分到一组中,然后得到若干个组,针对这些组分别使用聚合函数

语法

select column1,sum(column2)…… from table group by column1,column3;
  • 例:准备测试表和数据
mysql> insert into emp(name, role, salary) values
    -> ('马云','服务员', 1000.20),
    -> ('马化腾','游戏陪玩', 2000.99),
    -> ('孙悟空','游戏角色', 999.11),
    -> ('猪无能','游戏角色', 333.5),
    -> ('沙和尚','游戏角色', 700.33),
    -> ('隔壁老王','董事长', 12000.66);
Query OK, 6 rows affected (0.01 sec)
Records: 6  Duplicates: 0  Warnings: 0

+----+--------------+--------------+----------+
| id | name         | role         | salary   |
+----+--------------+--------------+----------+
|  1 | 马云         | 服务员       |  1000.20 |
|  2 | 马化腾       | 游戏陪玩     |  2000.99 |
|  3 | 孙悟空       | 游戏角色     |   999.11 |
|  4 | 猪无能       | 游戏角色     |   333.50 |
|  5 | 沙和尚       | 游戏角色     |   700.33 |
|  6 | 隔壁老王     | 董事长       | 12000.66 |
+----+--------------+--------------+----------+
6 rows in set (0.00 sec)

查询每个角色的最高工资、最低工资和平均工资

mysql> select role,max(salary),min(salary),avg(salary) from emp group by role;
+--------------+-------------+-------------+--------------+
| role         | max(salary) | min(salary) | avg(salary)  |
+--------------+-------------+-------------+--------------+
| 服务员       |     1000.20 |     1000.20 |  1000.200000 |
| 游戏角色     |      999.11 |      333.50 |   677.646667 |
| 游戏陪玩     |     2000.99 |     2000.99 |  2000.990000 |
| 董事长       |    12000.66 |    12000.66 | 12000.660000 |
+--------------+-------------+-------------+--------------+
4 rows in set (0.01 sec)

由于role这一列是group by指定的列,每一组的所有记录的role一定是相同的

如果分组之后不使用聚合函数,此时的结果就是查询出每一组中的某个代表数据,往往要搭配聚合函数使用,否则这里的查询结果就是没有意义的

  • 在group by中,可以一个SQL同时完成这两个类的筛选

注意:可搭配条件需要区分清楚,该条件是分组之前的条件还是分组之后的条件
分组之前:直接使用where即可,where子句一般写在group by前
分组之后:查询每个岗位的平均薪资,但是排除平均薪资超过2w的结果,须使用下列的HAVING描述条件

4.1.3HAVING

GROUP BY子句进行分组之后,需要对分组结果再进行条件过滤时,不能使用where语句,而需要用HAVING

having语句一般写在group by 的后面

  • 显示平均工资低于1500的角色和他的平均工资
mysql> select role,max(salary),min(salary),avg(salary) from emp group by role having avg(salary)<1500;
+--------------+-------------+-------------+-------------+
| role         | max(salary) | min(salary) | avg(salary) |
+--------------+-------------+-------------+-------------+
| 服务员       |     1000.20 |     1000.20 | 1000.200000 |
| 游戏角色     |      999.11 |      333.50 |  677.646667 |
+--------------+-------------+-------------+-------------+
2 rows in set (0.00 sec)

4.2联合查询

(面试大概率考,但是实际开发中,而是要非常限制的使用,有时候使用起来很爽,但又不能广泛而不加节制的使用)

  • 关键思路:理解笛卡尔积的工作原理

笛卡尔积:通过排列组合的方式得到一张更大的表,笛卡尔积的行数(列数)是这两个表的行数相加(列数相加),如果仔细观察可以看到其中有些数据是非法的(不符合实际情况,无意义),进行多表查询时,需要把有意义的数据筛选出来,无意义的数据过滤掉

在这里插入图片描述

4.2.1内连接

语法:

select 字段 from1 别名1 [inner] join2 别名2 on 连接条件 and 其他条件
select 字段 from1 别名1,表2 别名2 where 连接条件 and 其他条件
  • 例:查询许仙同学的成绩

步骤:

  1. 先把两个表进行笛卡尔积
mysql> select * from student,score ;
  1. 加上连接条件,筛选出有效数据
mysql> select * from student,score where student.id = score.student_id;
  1. 结合需求添加条件,针对结果进行筛选
mysql> select * from student,score where student.id = score.student_id and student.name = '许仙';
+----+------+--------+---------------+------------+----+-------+------------+-----------+
| id | sn   | name   | qq_mail       | classes_id | id | score | student_id | course_id |
+----+------+--------+---------------+------------+----+-------+------------+-----------+
|  4 |   31 | 许仙   | xuxian@qq.com |          1 | 10 |  67.0 |          4 |         1 |
|  4 |   31 | 许仙   | xuxian@qq.com |          1 | 11 |  23.0 |          4 |         3 |
|  4 |   31 | 许仙   | xuxian@qq.com |          1 | 12 |  56.0 |          4 |         5 |
|  4 |   31 | 许仙   | xuxian@qq.com |          1 | 13 |  72.0 |          4 |         6 |
+----+------+--------+---------------+------------+----+-------+------------+-----------+
4 rows in set (0.00 sec)
  1. 针对查询到的列进行精简
mysql> select student.name,score.score course from student,score where student.id = score.student_id and name = '许仙';
+--------+--------+
| name   | course |
+--------+--------+
| 许仙   |   67.0 |
| 许仙   |   23.0 |
| 许仙   |   56.0 |
| 许仙   |   72.0 |
+--------+--------+
4 rows in set (0.00 sec)
  • 例:查询所有同学的总成绩,及同学的个人信息
    此时同学的成绩是按照行来组织的,此处就是多行数据进行加和,聚合函数还需按同学进行分组
  1. 先进行笛卡尔积
mysql> select * from student,score where student.id = score.student_id;
  1. 指定连接条件
mysql> select * from student,score where student.id = score.student_id;
  1. 先精简列
mysql> select student.name,sum(score.score) from student,score where student.id = score.student_id;
  1. 针对上述结果进行group by聚合查询
mysql> select student.name,sum(score.score) from student,score where student.id = score.student_id group by name;
+-----------------+------------------+
| name            | sum(score.score) |
+-----------------+------------------+
| tellme          |            172.0 |
| 不想毕业        |            118.0 |
| 好好说话        |            178.0 |
| 白素贞          |            200.0 |
| 菩提老祖        |            119.5 |
| 许仙            |            218.0 |
| 黑旋风李逵      |            300.0 |
+-----------------+------------------+
7 rows in set (0.01 sec)
  • 例:查询所有同学的成绩以及个人信息
    列出每个同学,每门课程的的课程名字和分数
  1. 先进行笛卡尔积
mysql> select * from student,score,course;
  1. 指定连接条件筛选数据
mysql> select * from student,score,course where student.id = score.student_id  and course.id = score.course_id;
  1. 进行列的精简
mysql> select student.name,course.name,score.score from student,score,course where student.id = score.student_id and course.id = score.course_id;
+-----------------+--------------------+-------+
| name            | name               | score |
+-----------------+--------------------+-------+
| 黑旋风李逵      | Java               |  70.5 |
| 菩提老祖        | Java               |  60.0 |
| 白素贞          | Java               |  33.0 |
| 许仙            | Java               |  67.0 |
| 不想毕业        | Java               |  81.0 |
| 好好说话        | 中国传统文化       |  56.0 |
| tellme          | 中国传统文化       |  80.0 |
| 黑旋风李逵      | 计算机原理         |  98.5 |
| 白素贞          | 计算机原理         |  68.0 |
| 许仙            | 计算机原理         |  23.0 |
| 好好说话        | 语文               |  43.0 |
| 黑旋风李逵      | 高阶数学           |  33.0 |
| 菩提老祖        | 高阶数学           |  59.5 |
| 白素贞          | 高阶数学           |  99.0 |
| 许仙            | 高阶数学           |  56.0 |
| 不想毕业        | 高阶数学           |  37.0 |
| 黑旋风李逵      | 英文               |  98.0 |
| 许仙            | 英文               |  72.0 |
| 好好说话        | 英文               |  79.0 |
| tellme          | 英文               |  92.0 |
+-----------------+--------------------+-------+
20 rows in set (0.00 sec)

笛卡尔积的缺点:要提前考虑好表的数量,一旦表数量大或数目多,笛卡尔积大,如果对大表进行笛卡尔积,会产生大量临时结果,耗费时间,如果多表查询的数目非常多,SQL复杂,可读性差

4.2.2外连接

如果两个表里的记录都是存在对应关系,内外连接的结果一定是一致的,如果不存在对应关系,内外链接就会出现差别
外连接分为左外连接和右外连接,如果联合查询,左侧的表完全显示我们就说是左外连接,右侧的表完全显示我们就说是右外连接
左外连接就是以左侧的表为基准,保证左侧的表的每个数据都会在最终的结果里,如果在右侧表中不存在,对应的列就填成NULL
右外连接就是以右侧的表为基准,保证右侧的表的每个数据都会在最终的结果里,如果在右侧表中不存在,对应的列就填成NULL
语法:

-- 左外连接,表1完全显示
select 字段 from 表名1 left join 表名2 on 连接条件

-- 右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件
  • 例:查询所有同学的成绩以及个人信息,如果同学没有成绩,也需要表示
 -- “老外学中文”同学没有考试成绩也显示出来了
 -- 左外连接
 mysql> select * from student stu left join score sco on stu.id = sco.student_id; 
+----+-------+-----------------+------------------+------------+------+-------+------------+-----------+
| id | sn    | name            | qq_mail          | classes_id | id   | score | student_id | course_id |
+----+-------+-----------------+------------------+------------+------+-------+------------+-----------+
|  1 |  9982 | 黑旋风李逵      | xuanfeng@qq.com  |          1 |    1 |  70.5 |          1 |         1 |
|  1 |  9982 | 黑旋风李逵      | xuanfeng@qq.com  |          1 |    2 |  98.5 |          1 |         3 |
|  1 |  9982 | 黑旋风李逵      | xuanfeng@qq.com  |          1 |    3 |  33.0 |          1 |         5 |
|  1 |  9982 | 黑旋风李逵      | xuanfeng@qq.com  |          1 |    4 |  98.0 |          1 |         6 |
|  2 |   835 | 菩提老祖        | NULL             |          1 |    5 |  60.0 |          2 |         1 |
|  2 |   835 | 菩提老祖        | NULL             |          1 |    6 |  59.5 |          2 |         5 |
|  3 |   391 | 白素贞          | NULL             |          1 |    7 |  33.0 |          3 |         1 |
|  3 |   391 | 白素贞          | NULL             |          1 |    8 |  68.0 |          3 |         3 |
|  3 |   391 | 白素贞          | NULL             |          1 |    9 |  99.0 |          3 |         5 |
|  4 |    31 | 许仙            | xuxian@qq.com    |          1 |   10 |  67.0 |          4 |         1 |
|  4 |    31 | 许仙            | xuxian@qq.com    |          1 |   11 |  23.0 |          4 |         3 |
|  4 |    31 | 许仙            | xuxian@qq.com    |          1 |   12 |  56.0 |          4 |         5 |
|  4 |    31 | 许仙            | xuxian@qq.com    |          1 |   13 |  72.0 |          4 |         6 |
|  5 |    54 | 不想毕业        | NULL             |          1 |   14 |  81.0 |          5 |         1 |
|  5 |    54 | 不想毕业        | NULL             |          1 |   15 |  37.0 |          5 |         5 |
|  6 | 51234 | 好好说话        | say@qq.com       |          2 |   16 |  56.0 |          6 |         2 |
|  6 | 51234 | 好好说话        | say@qq.com       |          2 |   17 |  43.0 |          6 |         4 |
|  6 | 51234 | 好好说话        | say@qq.com       |          2 |   18 |  79.0 |          6 |         6 |
|  7 | 83223 | tellme          | NULL             |          2 |   19 |  80.0 |          7 |         2 |
|  7 | 83223 | tellme          | NULL             |          2 |   20 |  92.0 |          7 |         6 |
|  8 |  9527 | 老外学中文      | foreigner@qq.com |          2 | NULL |  NULL |       NULL |      NULL |
+----+-------+-----------------+------------------+------------+------+-------+------------+-----------+
21 rows in set (0.00 sec)

4.2.3自连接

自己和自己进行笛卡尔积,有时需要进行行和行的比较,而SQL只能进行行和列进行比较,此时就可以使用自连接,把行关系转成列关系

  • 例:查询成绩表中计算机原理成绩比Java成绩好的信息
mysql> select s1.student_id,s1.score,s2.score from score as s1,score as s2 where s1.student_id = s2.student_id and s1.course_id = 3 and s2.course_id = 1 and s1.score > s2.score;
+------------+-------+-------+
| student_id | score | score |
+------------+-------+-------+
|          1 |  98.5 |  70.5 |
|          3 |  68.0 |  33.0 |
+------------+-------+-------+
2 rows in set (0.01 sec)

4.2.4子查询

子查询的本质是套娃,把多个简单的SQL拼接成一个复杂的SQL,违背了一贯的变成原则

  • 例:查询与“不想毕业”的同班同学
mysql> select * from student where classes_id = (select classes_id from student where name = '不想毕业');
+----+------+-----------------+-----------------+------------+
| id | sn   | name            | qq_mail         | classes_id |
+----+------+-----------------+-----------------+------------+
|  1 | 9982 | 黑旋风李逵      | xuanfeng@qq.com |          1 |
|  2 |  835 | 菩提老祖        | NULL            |          1 |
|  3 |  391 | 白素贞          | NULL            |          1 |
|  4 |   31 | 许仙            | xuxian@qq.com   |          1 |
|  5 |   54 | 不想毕业        | NULL            |          1 |
+----+------+-----------------+-----------------+------------+
5 rows in set (0.00 sec)

4.2.5合并查询

把多个SQL的查询结果集合合并到一起
在实际应用中,为了合并多个select的执行结果,可以使用操作符union,union all。使用这两个时,前后查询的结果集中,字段需要一致
union:该操作符用于取得两个结果集的并集,当使用该操作符时,会自动去掉结果集中的重复行

  • 例:查询id小于3,或者名字为“英文”的课程
mysql> select * from course where id < 3 union select * from course where name = '英文';
+----+--------------------+
| id | name               |
+----+--------------------+
|  1 | Java               |
|  2 | 中国传统文化       |
|  6 | 英文               |
+----+--------------------+
3 rows in set (0.00 sec)

合并的两个SQL的结果集的列的个数和类型需要一致,union允许把两个不同的表查询结果合并到一起,并进行去重,若不想去重则使用union all

union all:不会去掉结果集中的重复行

  • 例:查询id小于3,或者名字为“Java”的课程
mysql> select * from course where id < 3 union all select * from course where name = '英文';
+----+--------------------+
| id | name               |
+----+--------------------+
|  1 | Java               |
|  2 | 中国传统文化       |
|  6 | 英文               |
+----+--------------------+
3 rows in set (0.00 sec)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2337051.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记录 | Pycharm中如何调用Anaconda的虚拟环境

目录 前言一、步骤Step1 查看anaconda 环境名Step2 Python项目编译器更改 更新时间 前言 参考文章&#xff1a; 参考视频&#xff1a;如何在pycharm中使用Anaconda创建的python环境 自己的感想 这里使用的Pycharm 2024专业版的。我所使用的Pycharm专业版位置&#xff1a;【仅用…

qt pyqt5的开发, 修改psd图像

这是引子, 需要将这个 photoshop-python-api 进行使用 https://juejin.cn/post/7445112318693621797#heading-4 这个是ps-python-api的官网, 在里面找api文档 https://pypi.org/project/photoshop-python-api/ 源码.gitee.url https://gitee.com/lbnb/psd_work.git 一. 安装必要…

Spring 中的循环依赖问题:解决方案与三级缓存机制

目录 Spring 中的循环依赖问题&#xff1a;解决方案与三级缓存机制什么是循环依赖&#xff1f;循环依赖的定义循环依赖的举例 Spring 中的循环依赖类型1. 构造器注入引发的循环依赖2. Setter 注入引发的循环依赖3. 字段注入&#xff08;Autowired&#xff09;引发的循环依赖 Sp…

ios接入穿山甲【Swift】

1.可接入的广告&#xff0c;点击右下角查看接入文档 https://www.csjplatform.com/union/media/union/download/groMore 2.进入接入文档&#xff0c;选择最新版本进行接入 pod Ads-CN-Beta,6.8.0.2pod GMGdtAdapter-Beta, 4.15.22.0pod GDTMobSDK,4.15.30pod KSAdSDK,3.3.74.0p…

电脑一直不关机会怎么样?电脑长时间不关机的影响

现代生活中&#xff0c;许多人会让自己的电脑24小时不间断运行&#xff0c;无论是为了持续的工作、娱乐&#xff0c;还是出于忘记关机的习惯。然而&#xff0c;电脑长时间不关机&#xff0c;除了提供便利之外&#xff0c;也可能对设备的健康产生一系列影响。本文将为大家介绍电…

vue3 当页面显示了 p/span/div 标签 想要转换成正常文字

返回值有标签出现时&#xff0c;使用v-html 解决 <p>{{ item.content }}</p> //页面直接显示接口返回的带标签的数据 <p v-html"item.content "></p> //转换成html文件 显示正常文字各种样式 问题&#xff1a; 解决&#xff1a;v-html 显…

Elasticsearch 8.18 中提供了原生连接 (Native Joins)

作者&#xff1a;来自 Elastic Costin Leau 探索 LOOKUP JOIN&#xff0c;这是一条在 Elasticsearch 8.18 的技术预览中提供的新 ES|QL 命令。 很高兴宣布 LOOKUP JOIN —— 这是一条在 Elasticsearch 8.18 的技术预览中提供的新 ES|QL 命令&#xff0c;旨在执行左 joins 以进行…

k8s蓝绿发布

k8s蓝绿发布 什么是蓝绿部署K8S中如何实现蓝绿部署k8s蓝绿部署流程图 什么是蓝绿部署 参考: https://youtu.be/CLq_hA0lAd0 https://help.coding.net/docs/cd/best-practice/blue-green.html 蓝绿部署最早是由马丁福勒 2010年在他的博客中提出. 蓝绿部署是一种软件部署策略,用…

链接世界:计算机网络的核心与前沿

计算机网络引言 在数字化时代&#xff0c;计算机网络已经成为我们日常生活和工作中不可或缺的基础设施。从简单的局域网&#xff08;LAN&#xff09;到全球互联网&#xff0c;计算机网络将数以亿计的设备连接在一起&#xff0c;推动了信息交换、资源共享以及全球化的进程。 什…

记录Docker部署CosyVoice V2.0声音克隆

#记录工作 CosyVoice 是由 FunAudioLLM 团队开发的一个开源多语言大规模语音生成模型&#xff0c;提供了从推理、训练到部署的全栈解决方案。 项目地址&#xff1a; https://github.com/FunAudioLLM/CosyVoice.git 该项目目前从v1.0版本迭代到v2.0版本&#xff0c;但是在Wind…

MCU刷写——HEX与S19文件互转详解及Python实现

工作之余来写写关于MCU的Bootloader刷写的相关知识,以免忘记。今天就来聊聊Hex与S19这这两种文件互相转化,我是分享人M哥,目前从事车载控制器的软件开发及测试工作。 学习过程中如有任何疑问,可底下评论! 如果觉得文章内容在工作学习中有帮助到你,麻烦点赞收藏评论+关注走…

全链路开源数据平台技术选型指南:六大实战工具链解析

在数字化转型加速的背景下&#xff0c;开源技术正重塑数据平台的技术格局。本文深度解析数据平台的全链路架构&#xff0c;精选六款兼具创新性与实用性的开源工具&#xff0c;涵盖数据编排、治理、实时计算、联邦查询等核心场景&#xff0c;为企业构建云原生数据架构提供可落地…

Dify智能体平台源码二次开发笔记(5) - 多租户的SAAS版实现(2)

目录 前言 用户的查询 controller层 添加路由 service层 用户的添加 controller层 添加路由 service层-添加用户 service层-添加用户和租户关系 验证结果 结果 前言 完成租户添加功能后&#xff0c;下一步需要实现租户下的用户管理。基础功能包括&#xff1a;查询租…

Linux的目录结构(介绍,具体目录结构)

目录 介绍 具体目录结构 简洁的目录解释 详细的目录解释 介绍 Linux的文件系统是采用级层式的树状目录结构&#xff0c;在此结构的最上层是根目录“/”。Linux的世界中&#xff0c;一切皆文件&#xff08;比如&#xff1a;Linux会把硬件映射成文件来管理&#xff09; 具体目…

如何用 esProc 补充数据库 SQL 的缺失能力

某些数据库 SQL 缺失必要的能力&#xff0c;通常要编写大段的代码&#xff0c;才能间接实现类似的功能&#xff0c;有些情况甚至要改用存储过程&#xff0c;连结构都变了。常见的比如&#xff1a;生成时间序列、保持分组子集、动态行列转换、自然序号、相对位置、按序列和集合生…

晶晨线刷工具下载及易错点说明:Key文件配置错误/mac剩余数为0解决方法

晶晨线刷工具下载及易错点说明&#xff1a;Key文件配置错误&#xff0f;mac剩余数为0解决方法 各种版本晶晨线刷工具下载&#xff1a; 晶晨线刷工具易出错点故障解决方法&#xff1a; 1、晶晨线刷工具加载固件的时候提示mac红字且剩余数为0的解决办法 很多同学可能会与遇到加…

论文阅读:Invertible Grayscale

这是一篇 ACM Transactions on Graphic 上的文章&#xff0c;这篇文章中介绍的应用还挺有意思的&#xff0c;关于可逆的图像灰度化。 Abstract 一旦彩色图像被转换为灰度图像&#xff0c;人们普遍认为&#xff0c;即使采用最先进的彩色化方法&#xff0c;原始颜色也无法完全恢…

关于ResNet和FPN的一份介绍

在这篇文章中我将介绍ResNet和FPN这两个深度学习中重要的技术。 一、ResNet-50/101 首先我们先来看ResNet技术&#xff1a; 1.1 概述 ResNet技术是基于残差学习&#xff0c;引入Bottleneck技术以及Shortcut Connection技术&#xff0c;而去解决神经网络中的退化问题。 1.2…

AI大模型学习九:‌Sealos cloud+k8s云操作系统私有化一键安装脚本部署完美教程

一、说明 ‌Sealos‌是一款基于Kubernetes&#xff08;K8s&#xff09;的云操作系统发行版&#xff0c;它将K8s以及常见的分布式应用如Docker、Dashboard、Ingress等进行了集成和封装&#xff0c;使得用户可以在不深入了解复杂的K8s底层原理的情况下&#xff0c;快速搭建起一个…

详解关于VS配置好Qt环境之后但无法打开ui界面

目录 找到Qt安装目录中designer.exe的路径 找到vs中的解决方案资源管理器 右键ui文件&#xff0c;找到打开方式 点击添加 然后把前面designer.exe的路径填到程序栏中&#xff0c;点击确定 然后设置为默认值&#xff0c;并点击确定 当在vs中配置好Qt环境之后&#xff0c;但…