news 2026/10/21 8:44:14

MySQL中的常用SQL语句

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MySQL中的常用SQL语句

SQL语句的分类

  • DDL(Data Definition Languages)语句:

    数据定义语言,这些语句定义了不同的数据段、数据库、表、列、索引等数据库对象的定义。常用的语句关键字主要包括create、drop、alter、rename、truncate。其中 create 用于创建数据库对象,drop 用于删除数据库对象,alter 用于修改已有对象的结构,rename 用于重命名对象,truncate 用于清空表中的数据但保留表结构。DDL 语句执行后通常会自动提交事务,且操作不可回滚,因此在使用时需要格外谨慎。

  • DML(Data Manipulation Language)语句:

    数据操纵语句,用于添加、删除、更新和查询数据库记录,并检查数据完整性,常用的语句关键字主要包括insert、delete、update等。insert 用于向表中插入新的记录,delete 用于删除表中符合条件的记录,update 用于修改表中已有记录的数据。与 DDL 不同,DML 语句操作的是表中的数据而非表结构本身,并且可以通过事务控制实现回滚,从而保证数据操作的安全性和一致性。

  • DCL(Data Control Language)语句:

    数据控制语句,用于控制不同数据段之间的许可和访问级别的语句。这些语句定义了数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括grant、revoke等。grant 用于向用户授予访问权限,revoke 用于收回已授予的权限。通过合理使用 DCL 语句,数据库管理员可以精确控制不同用户对数据库资源的访问范围,有效保障数据的安全性和隐私性。

  • DQL(Data Query Language)语句:

    数据查询语句,用于从一个或多个表中检索信息。主要的语句关键字包括select,它是数据库操作中使用频率最高、功能最丰富的语句。select 可以配合 where 条件过滤、order by 排序、group by 分组、join 多表关联以及聚合函数等子句,灵活地从数据库中提取所需的数据。DQL 语句不会修改数据库中的数据,只负责读取和展示查询结果,是日常开发与数据分析中最常用的 SQL 类型。

数据库的基本操作

一.增

1.创建数据库

#基本用法 create database 数据库名称; #创建db1库 mysql> create database db1; #创建db2库并指定默认字符集 mysql> create database db2 default charset utf8mb4; #如果存在不报错(if not exists) mysql> create database if not exists db3 default charset utf8mb4;

2.创建数据表

# 基本语法 create table 数据表名称( 字段1 字段类型 [字段约束], 字段2 字段类型 [字段约束], ... ); # 在数据库db_test中创建一个article文章表,拥有4个字段(编号、标题、作者、内容) mysql> use db_test; mysql> create table tb_article( id int not null auto_increment primary key, username varchar(20), password char(32), content text ) engine=innodb default charset=utf8mb4;

3.插入数据

#基本用法 insert into 数据表名称([字段1,字段2...]) values (字段1的值,字段2的值...); #向tb_article插入两条数据 mysql> insert into tb_article values (null,'张三','123456','内容1'),(null,'李四','112233','内容2'); mysql> insert into tb_article(username,password) values ('王五','123321');

二.删

1.删除数据库

#基本用法 drop database 数据库名称; mysql> drop database db_test;

2.删除数据表

#基本用法 drop table 数据表名称; #删除本库的数据表tb_test(先创建create table tb_test (id int);) mysql> drop table tb_test;

3.删除数据

#基本用法 delete from 数据表名称 [where 删除条件]; #删除tb_article中id为2的数据 mysql> delete from tb_article where id=2;
# 清空数据表 mysql> delete from 数据表; 或 mysql> truncate 数据表;

delete from与truncate区别在哪里?

delete:删除数据记录,数据操作语言(DML)

  • 在事务控制里,DML语句要么commit,要么rollback
  • 删除大量记录速度慢,只删除数据不回收高水位线,可以带条件删除

truncate:删除所有数据记录,数据定义语言(DDL)

  • 不在事务控制里,DDL语句执行前会提交前面所有未提交的事务
  • 清里大量数据速度快,回收高水位线(high water mark),不能带条件删除

三.改

1.修改数据库的信息

#不能修改数据库名称,只能修改数据库编码格式 mysql> alter database 数据库名称 default charset=新编码格式; mysql> alter database db1 default charset=gbk;

2.修改数据表

1.添加数据表字段

#基本用法 alter table 数据表名称 add 新字段名称 字段类型 first/after 其他字段名称; #选项说明: first:把新添加字段放在第一位 after 字段名称:把新添加字段放在指定字段的后面 #在tb_article文章表中添加一个addtime字段,类型为date(年-月-日) mysql> alter table tb_article add addtime date after content; mysql> desc tb_article;

2.修改字段名称与字段类型

注意:

  • 修改字段类型必须带上原有约束
  • 如果已有数据长度超过新长度,会报错;
  • 类型转换,比如varchar转int,字符串不是数字会失败
#修改字段名称与字段类型 mysql> alter table tb_article change username user varchar(40); mysql> desc tb_article; #只修改字段的类型 mysql> alter table tb_article modify user varchar(50); mysql> desc tb_article; #只修改字段名称(类型不变) mysql> alter table tb_article change password passwd char(32); #(mysql8.0+) mysql> alter table tb_article rename column password to passwd;

3.删除某个字段

#基本用法 alter table tb_article drop 字段名称; #删除article表中的addtime字段 mysql> alter tb_article drop addtime; mysql> desc tb_article;

4.修改数据表引擎

mysql> alter table tb_article engine=myisam; mysql> show create table tb_article;

5.修改数据表的编码格式

mysql> alter table tb_article default charset=gbk; mysql> show create table tb_article;

6.修改数据表名称

#移动表到另一个库里并重命名 rename table db_test.tb_article to db1.article; 或者(use db1;show tables;) alter table db1.artile rename db_test.tb_article; #只重命名表名不移动 rename table tb_article to article; 或者(show tables;) alter table article rename tb_article;

3.修改数据

#基本用法 update 数据表名称 set 字段1=更新后的值,字段2=更新后的值,... where 更新条件; #将username='张三'这条数据的conten修改为法外狂徒 mysql> update tb_article set content='法外狂徒' where name='张三';

四.查

1.查询已创建的数据库

#显示所有数据库 mysql> show databases; #显示某个数据库的数据结构 mysql> show create database db1;

2.查询已创建数据表

#查询当前数据库所有数据表 mysql> use 数据库名称; mysql> show tables; #查询数据表的创建过程 mysql> show create table 数据表名称; 或 mysql> desc 数据表名称;

3.查询数据

# 基本用法 select * from 数据表名称 [where 查询条件]; select id,username from 数据表名称 [where 查询条件]; # 简单示例:查询tb_article表中的所有记录 mysql> select * from tb_article; # 简单示例:查询tb_article表中id,username字段对应的信息 mysql> select id,username from tb_article; # 简单示例:查询tb_article表中id>2的所有信息 mysql> select * from tb_article where id>2; # 简单示例:查询tb_article表中name为张三的信息 mysql> select * from tb_article where name='张三';

详细使用见七.sql查询语句

五.用户权限

1.用户管理

1.创建用户

MySQL中不能单纯通过用户名来说明用户,必须要加上主机。如==jack@10.1.1.1==,且在mysql服务器上书写创建用户的语句

# 基本用法 create user '用户名'@'被允许连接的主机名称或主机的IP地址' identified by '用户密码'; # 创建一个MySQL账号,用户名:tom,用户密码:123 mysql> create user 'tom'@'localhost' identified by '123'; 或 mysql> create user 'tom'@'127.0.0.1' identified by '123'; # 创建一个MySQL账号(要求开通远程连接),主机IP地址:10.1.1.23,用户名:harry,用户密码:123 mysql> create user 'harry'@'10.1.1.23' identified by '123'; # 创建一个MySQL账号(要求开通远程连接),要求面向所有主机开放,用户名:root,用户密码:123 mysql> create user 'root'@'%' identified by '123';

2.删除用户

# 基本用法 mysql> drop user '用户名'@'主机名称或主机的IP地址'; #注意: 如果在删除用户时没有指定主机的名称或主机的IP地址,则默认删除这个账号的所有信息。 # 删除tom这个账号 mysql> drop user 'tom'@'localhost'; # 删除harry这个账号 mysql> drop user 'harry'@'10.1.1.%';

3.修改用户

MySQL用户重命名通常可以更改两部分,一部分是用户的名称,一部分是被允许访问的主机名称或主机的IP地址。

# 基本用法 mysql> rename user 旧用户信息 to 新用户信息; # 把用户'root'@'%'更改为'root'@'localhost' mysql> rename user 'root'@'%' to 'root'@'localhost'; # 把'tom'@'localhost'更名为'harry'@'localhost' mysql> create user 'tom'@'localhost' identified by '123'; mysql> rename user 'tom'@'localhost' to 'harry'@'localhost';

2.权限管理

1.授予权限

# 基本用法 mysql> grant 权限1,权限2 on 库.表 to 用户@主机 mysql> grant 权限(列1,列2,...) on 库.表 to 用户@主机 # 给tom账号分配db1的查询权限 mysql> grant select on db_test.* to 'tom'@'localhost'; mysql> flush privileges; # 给tom账号分配db_test数据的tb.article数据表的查询权限(要求只能更改class_name字段) mysql> grant select(user) on db_test.tb.article to 'tom'@'localhost'; mysql> flush privileges # 添加一个root@%账号,然后分配所有权限 mysql> create user 'root'@'%' identified by '123'; mysql> grant all on *.* to 'root'@'%'; mysql> flush privileges;

2.查询权限

# 查询当前用户权限 show grants; # 查询其他用户权限 show grants for '用户名称'@'授权的主机名称或IP地址';

3.转发权限

with grant option选项作用:代表此账号可以向其他用户转发其拥有的权限,但是转发的权限不能超过自身权限。如果grant授权时没有with grant option选项,则其无法为其他用户转发授权。

# root授予test转发权限的权力 mysql> grant all on *.* to 'test'@'localhost' with grant option; # 创建test1用户后再登录test去授予其查询的权限 mysql>grant select on db_test.* to 'test'@'localhost'; # root没有授予test2转发权限的权力 mysql> grant all on *.* to 'test2'@'localhost' identified by '123'; # 创建test3后登录test2尝试转发权限会报错

4.回收权限

# 基本用法 revoke 权限 on 库.表 from 用户; # 撤消指定的权限(回收tom的db_test库,tb_article表的select权限) mysql> revoke select on db_test.tb_article from 'tom'@'localhost'; mysql> flush privileges; mysql> show grants for 'tom'@'localhost'; # 撤消所有的权限 mysql> revoke all on *.* from 'tom'@'localhost';

六.数据类型

数值-整数类型:

  • tinyint:1 字节,范围最小,常用来做状态标识(0/1)
  • smallint:2 字节
  • mediumint:3 字节
  • int:4 字节,开发最常用主键 / 普通数字字段
  • bigint:8 字节,数值很大时使用,雪花 ID、大自增主键推荐

数值-小数类型:

  • DECIMAL/UMERIC:定点数,精度绝对准确。适合金额、财务计算,不会丢失精度,可自定义总长度和小数位数。。
  • FLOAT:单精度浮点数,4 字节,大约 7 位有效数字;数值越大精度越低,不适合金额。
  • DOUBLE:双精度浮点数,8 字节,大约 15 位有效数字,同样是近似存储,存在精度丢失风险。

字符串类型:

  • CHAR:定长字符串,长度 0~255。分配固定存储空间,不足长度自动空格填充;读取时尾部空格移除。占用空间和字符集相关:utf8 一个中文 3 字节,gbk 中文 2 字节。查询速度快,适合长度固定内容(手机号、身份证)。
  • VARCHAR:变长字符串,按需占用空间。额外用 1~2 字节记录真实数据长度,MySQL 上限 65535 字节,实际可用 65532 字节。适合长短不一的文本(名称、简介)。
  • TEXT:大文本类型。当文本长度超出 VARCHAR 合适范围时选用,适合长文章、大段文字;不能设置默认值。

时间类型:

  • DATE:日期YYYY-MM-DD,只存年月日。
  • TIME:时间HH:MM:SS,只存时分秒。
  • DATETIME:日期时间YYYY-MM-DD HH:MM:SS,范围大,不受时区影响,业务开发首选。
  • TIMESTAMP:时间戳YYYY-MM-DD HH:MM:SS,底层存时间戳,受时区影响,范围比 DATETIME 小。
  • YEAR:年份类型,仅保存年份。

其他类型:

  • BLOB:保存二进制的大型数据(字节串),没有字符集,如:图片、音频视频等。
  • ENUM枚举类型:多选一,从给定的多个选项中选择一个,如:gender enum('男','女','保密')
  • ET集合类型:多选多,从给定的多个选项中选个多个,如:hobby set('吃饭','睡觉','打豆豆')

七.sql查询语句

常用符号说明:

符号说明
%匹配0个或任意多个字符
_匹配单个字符
like模糊匹配
=等于,精确匹配
>大于
<小于
>=大于等于

<=

小于等于
!= 或 <>不等于
! 或 not逻辑非
|| 或 or逻辑或
&& 或 and逻辑与
between ...and...两者之间(包括边界)
in(...)在...
not in(...)不在...

简单统计函数:

常见统计函数说明
max求最大值
min求最小值
avg求平均值
sum求总和
count求总行数

测试用表:

建表:

CREATE TABLE student_score ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', student_name VARCHAR(20) NOT NULL COMMENT '学生姓名', class_name VARCHAR(20) NOT NULL COMMENT '班级', subject VARCHAR(20) NOT NULL COMMENT '科目', score TINYINT NOT NULL COMMENT '分数', create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

说明:

  • ENGINE=InnoDB:指定存储引擎,默认事务引擎
  • DEFAULT CHARSET=utf8mb4:字符集,完整支持中文、emoji
  • COLLATE=utf8mb4_unicode_ci:排序规则,ci代表大小写不敏感

插入数据:

INSERT INTO student_score (student_name,class_name,subject,score) VALUES ('张三','一班','MySQL',88), ('张三','一班','Java',76), ('李四','一班','MySQL',92), ('李四','一班','Java',81), ('王五','二班','MySQL',59), ('王五','二班','Java',66), ('赵六','二班','MySQL',77), ('赵六','二班','Java',95), ('孙七','一班','MySQL',45), ('孙七','一班','Java',72), ('周八','二班','MySQL',83), ('周八','二班','Java',89);
mysql> select * from student_score; +----+--------------+------------+---------+-------+---------------------+ | id | student_name | class_name | subject | score | create_time | +----+--------------+------------+---------+-------+---------------------+ | 1 | 张三 | 一班 | MySQL | 88 | 2026-10-09 13:56:50 | | 2 | 张三 | 一班 | Java | 76 | 2026-10-09 13:56:50 | | 3 | 李四 | 一班 | MySQL | 92 | 2026-10-09 13:56:50 | | 4 | 李四 | 一班 | Java | 81 | 2026-10-09 13:56:50 | | 5 | 王五 | 二班 | MySQL | 59 | 2026-10-09 13:56:50 | | 6 | 王五 | 二班 | Java | 66 | 2026-10-09 13:56:50 | | 7 | 赵六 | 二班 | MySQL | 77 | 2026-10-09 13:56:50 | | 8 | 赵六 | 二班 | Java | 95 | 2026-10-09 13:56:50 | | 9 | 孙七 | 一班 | MySQL | 45 | 2026-10-09 13:56:50 | | 10 | 孙七 | 一班 | Java | 72 | 2026-10-09 13:56:50 | | 11 | 周八 | 二班 | MySQL | 83 | 2026-10-09 13:56:50 | | 12 | 周八 | 二班 | Java | 89 | 2026-10-09 13:56:50 | +----+--------------+------------+---------+-------+---------------------+

1.where子句

#查询科目是 MySQL 的所有成绩 SELECT * FROM student_score WHERE subject = 'MySQL'; #查询分数大于 80 分的记录 SELECT * FROM student_score WHERE score > 80; #查询分数小于 60 分(不及格) SELECT * FROM student_score WHERE score < 60; #分数≥90 分 SELECT * FROM student_score WHERE score >= 90; #分数≤70 分 SELECT * FROM student_score WHERE score <=70; #查询班级不是一班的数据(两种写法等价) SELECT * FROM student_score WHERE class_name != '一班'; 或 SELECT * FROM student_score WHERE class_name <> '一班'; #一班,并且 MySQL 科目,分数 > 80 SELECT * FROM student_score WHERE class_name='一班' AND subject='MySQL' AND score>80; #分数大于 90 或者 小于 60 SELECT * FROM student_score WHERE score >90 OR score <60; #查询不是 Java 科目的数据 SELECT * FROM student_score WHERE NOT subject = 'Java'; SELECT * FROM student_score WHERE subject != 'Java'; #查询姓名以 “张” 开头的学生 SELECT * FROM student_score WHERE student_name LIKE '张%'; #姓名是两个字,第一个字是 “赵”:赵_ SELECT * FROM student_score WHERE student_name LIKE '赵_'; #分数在 70 ~ 90 之间,包含 70 和 90 SELECT * FROM student_score WHERE score BETWEEN 70 AND 90; #查询姓名是张三、李四的记录 SELECT * FROM student_score WHERE student_name IN ('张三','李四'); #查询姓名不是张三、李四的记录 SELECT * FROM student_score WHERE student_name NOT IN ('张三','李四'); #一班学生,分数大于 70,科目是 MySQL 或者 Java,排除张三 SELECT * FROM student_score WHERE class_name='一班' AND score>70 AND subject IN ('MySQL','Java') AND student_name NOT IN ('张三');

2.group by子句

#按班级分组,统计每个班级多少条成绩记录 SELECT class_name, COUNT(*) AS record_count FROM student_score GROUP BY class_name; #按学科分组,统计每个班级的平均分 SELECT subject, AVG(score) AS avg_score FROM student_score GROUP BY subject; #按学生姓名分组,求每个学生总分、平均分、最高分、最低分 SELECT student_name, SUM(score) AS total_score, AVG(score) AS avg_score, MAX(score) AS max_score, MIN(score) AS min_score FROM student_score GROUP BY student_name;

3.having子句

# GROUP BY + HAVING,筛选【学生总分大于 150】的学生 SELECT student_name, SUM(score) AS total_score FROM student_score GROUP BY student_name HAVING SUM(score) > 150; # WHERE 先过滤原始数据,再 GROUP BY 分组,再 HAVING 过滤分组结果 SELECT student_name, AVG(score) AS java_avg FROM student_score WHERE subject = 'Java' GROUP BY student_name HAVING AVG(score) >75; # 按班级分组,求班级 MySQL 科目平均分,只保留平均分大于 70 的班级 SELECT class_name, AVG(score) mysql_avg FROM student_score WHERE subject = 'MySQL' GROUP BY class_name HAVING AVG(score) > 70; # 综合,按班级 + 科目两个字段联合分组 SELECT class_name, subject, AVG(score) AS avg_score FROM student_score GROUP BY class_name, subject HAVING AVG(score) > 80; # 按班级分组,计算各班总分,只展示班级总分大于 300 的班级 SELECT class_name,SUM(score) AS total_score FROM student_score GROUP BY class_name HAVING SUM(score) > 300;

4.order by子句

# 按分数降序,分数高的在前 SELECT student_name,subject,score FROM student_score ORDER BY score DESC; # 只看 MySQL 科目,分数从小到大排序 SELECT student_name,score FROM student_score WHERE subject='MySQL' ORDER BY score ASC; # 先按班级升序,同班内部按分数降序 SELECT class_name,student_name,subject,score FROM student_score ORDER BY class_name ASC, score DESC; # 先按班级升序,同班内部按Java科目分数降序 SELECT class_name,student_name,subject,score FROM student_score WHERE subject='Java' ORDER BY class_name ASC, score DESC;

5.limit子句

# ORDER BY + LIMIT 取Top3,分数最高的3条成绩 SELECT student_name,subject,score FROM student_score ORDER BY score DESC LIMIT 3; #查询所有 Java 科目成绩,分数降序,只取前 4 名 SELECT student_name,subject,score FROM student_score WHERE subject='Java' ORDER BY score DESC LIMIT 4; # 分页写法LIMIT offset,rows;跳过前2条,取后面3条 SELECT student_name,subject,score FROM student_score ORDER BY score DESC LIMIT 2,3; # 按班级 + 科目分组,计算平均分,只保留平均分>80的分组,平均分降序,只取前2条 SELECT class_name, subject, AVG(score) AS avg_score FROM student_score GROUP BY class_name, subject HAVING AVG(score) > 80 ORDER BY avg_score DESC LIMIT 2;

6.多表查询

新建teacher教师表:

CREATE TABLE teacher ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT '教师id', t_name VARCHAR(20) NOT NULL COMMENT '教师姓名', subject VARCHAR(20) NOT NULL COMMENT '授课科目', create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

插入测试数据:

INSERT INTO teacher(t_name,subject) VALUES ('李老师','MySQL'), ('王老师','Java'), ('陈老师','Python'), ('刘老师','MySQL');
mysql> select * from teacher; +----+-----------+---------+---------------------+ | id | t_name | subject | create_time | +----+-----------+---------+---------------------+ | 1 | 李老师 | MySQL | 2026-10-09 15:27:42 | | 2 | 王老师 | Java | 2026-10-09 15:27:42 | | 3 | 陈老师 | Python | 2026-10-09 15:27:42 | | 4 | 刘老师 | MySQL | 2026-10-09 15:27:42 | +----+-----------+---------+---------------------+

1.union联合查询

作用:把多条 SELECT 语句的结果纵向拼接(上下叠加)

注意:

  • 多条 select 的列数量必须一致
  • 列的数据类型顺序要对应
  • UNION:自动去重;UNION ALL:不去重,性能更高(常用)
  • 字段名以第一条 select 的列名为准
# union自动去重 # 取出所有学生科目 和 所有教师授课科目,合并,去掉重复科目 SELECT subject FROM student_score UNION SELECT subject FROM teacher; # union all 不去重直接拼接 # 展示全部记录,重复的 MySQL、Java 都会保留,性能比 UNION 更好 SELECT subject FROM student_score UNION ALL SELECT subject FROM teacher; # 查询80分以上的学生姓名和全部老师姓名 SELECT student_name AS name FROM student_score WHERE score >80 UNION ALL SELECT t_name AS name FROM teacher; # 联合查询时排序要写在整体联合查询的最后 SELECT subject FROM student_score UNION SELECT subject FROM teacher ORDER BY subject;

2.交叉查询

含义:A 表每一行 和 B 表每一行全部两两组合,没有匹配条件,不写ON结果行数 = A 表行数 × B 表行数,数据量大的时候,结果会爆炸式增长

# 查学生姓名、老师姓名、科目 SELECT s.student_name, t.t_name, s.subject FROM student_score s CROSS JOIN teacher t; # student_score和teacher交叉连接,只看MySQL科目的组合 SELECT s.student_name,t.t_name,s.subject FROM student_score s CROSS JOIN teacher t; where s.sbject = 'MySQL' AND t.sbject='MySQL';

3.内连接查询

# 基本用法 mysql> select 数据表1.字段列表,数据表2.字段列表 from 数据表1 inner join 数据表2 on 连接条件; # 查询学生姓名、学生分数、老师姓名、科目;只取出科目相同的记录 SELECT s.student_name, s.score, t.t_name, s.subject FROM student_score s INNER JOIN teacher t ON s.subject = t.subject; # 查询科目相同,并且学生分数大于80的师生信息 SELECT s.student_name, s.score, t.t_name, s.subject FROM student_score s INNER JOIN teacher t ON s.subject = t.subject WHERE s.score > 80; # 按老师分组,统计每个老师对应的学生平均分 SELECT t.t_name, AVG(s.score) AS avg_score FROM student_score s INNER JOIN teacher t ON s.subject = t.subject GROUP BY t.t_name;

4.外连接查询

# 基本用法 select 数据表1.字段列表,数据表2.字段列表 from 数据表1 left join 数据表2 on 连接条件; # 学生姓名、班级、分数、科目、授课老师 SELECT s.student_name, s.class_name, s.score, s.subject, t.t_name FROM student_score s LEFT JOIN teacher t ON s.subject = t.subject; # 统计每个学生的成绩,以及对应的授课老师,只看一班学生 SELECT s.student_name, s.subject, s.score, t.t_name FROM student_score s LEFT JOIN teacher t ON s.subject = t.subject WHERE s.class_name = '一班'; # 右连接与左连接类似,但是可读性差,一般不用 # 查询全部老师,以及对应学生成绩,没有学生的老师信息也保留 SELECT s.student_name, s.score, t.t_name, t.subject FROM student_score s RIGHT JOIN teacher t ON s.subject = t.subject;

7.子查询

一条 SELECT 语句里面嵌套另外一条 SELECT 语句,嵌套的这一段就是子查询

注意:

  • 子查询优先执行,子查询结果作为外层 SQL 的条件 / 数据源
  • 子查询尽量不要返回大量数据,性能一般
  • 关键字:IN/NOT IN/> < =/EXISTS
# 查询分数高于平均分的所有学生成绩 SELECT * FROM student_score WHERE score > (SELECT AVG(score) FROM student_score); # 查询有老师授课的科目对应的学生成绩 SELECT * FROM student_score WHERE subject IN (SELECT subject FROM teacher); # 查询科目没有授课老师的学生成绩 SELECT * FROM student_score WHERE subject NOT IN (SELECT subject FROM teacher); # 查询存在授课老师的学生成绩 SELECT * FROM student_score s WHERE EXISTS (SELECT 1 FROM teacher t WHERE s.subject = t.subject); # 先算出每个学生总分,再查询总分大于150的学生 SELECT * FROM ( SELECT student_name, SUM(score) AS total_score FROM student_score GROUP BY student_name ) AS temp_stu WHERE total_score > 150; # 查询学生姓名、科目、分数,同时展示全部学生平均分 SELECT student_name, subject, score, (SELECT AVG(score) FROM student_score) AS all_avg_score FROM student_score;
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/18 17:29:08

【BFS 解决拓扑排序】课程表

文章目录题目解析算法原理建图入度数组代码实现题目链接&#xff1a;207. 课程表 题目解析 拓扑排序&#xff08;Topological sorting&#xff09;要解决的问题是 如何给一个有向无环图的所有节点排序。 有向无环图 &#xff08;Directed Acyclic Graph, 缩写 DAG&#xff09…

作者头像 李华
网站建设 2026/10/20 18:10:34

PHP四大加密技术全解析+实战笔记免费领

在PHP语言里, 加密的操作方式主要有那四种常用的办法。除了刚才提到的这几个方法以外, 还有一种跟网址链接相关的加密处理以及解密的方式是另外一种存在的情况。我希望这段文字内容对于你们正在进行的软件开发工作能够提供一点实际的帮助作用和使用价值参考。 另外, 我把之后整…

作者头像 李华
网站建设 2026/10/18 22:12:26

气源含水对气液增压器的故障影响有多大?选台湾钰腾从根源规避风险

很多机加工车间都有一个常年被忽略的隐形隐患&#xff1a;气源里的水。尤其是南方梅雨季、北方冬季温差大的时段&#xff0c;空压机出来的压缩空气里混着大量冷凝水&#xff0c;哪怕装了普通的油水分离器&#xff0c;也很难完全过滤干净。这些混在气源里的水顺着管路钻进气液增…

作者头像 李华
网站建设 2026/10/18 3:03:52

OSI与TCP/IP分层模型实战:从理论到网络故障排查

计算机网络这门课&#xff0c;很多人是把它当“死知识”来背的&#xff1a;OSI七层是哪七层、TCP/IP有哪几个协议、三次握手发几个包……背得滚瓜烂熟&#xff0c;一旦真碰上网络故障&#xff0c;照样不知道从哪下手。我带过的不少新人都有这个问题。究其原因&#xff0c;是没有…

作者头像 李华
网站建设 2026/10/16 6:55:25

视觉SLAM第7讲|特征点法、对极几何与位姿求解全梳理

视觉SLAM第7讲&#xff5c;视觉里程计(上)&#xff1a;特征点法、对极几何与位姿求解全梳理 如果说前面几讲的刚体运动、李群李代数是SLAM的「数学工具包」&#xff0c;那从这一讲开始&#xff0c;我们就正式进入视觉SLAM的核心前端模块——视觉里程计&#xff08;Visual Odome…

作者头像 李华