当前位置: 首页 > news >正文

06.MySQL数据库操作详解

06.MySQL数据库操作详解:CRUD与查询优化

📚 文章目录

1️⃣ MySQL表的增删查改

  • CRUD操作的核心地位

2️⃣ Create - 数据新增

  • 单行全列插入
  • 多行指定列插入
  • 插入否则更新
  • 替换数据

3️⃣ Retrieve - 数据查询

  • 全列查询
  • 指定列查询
  • 表达式查询
  • 结果去重

4️⃣ WHERE条件筛选

  • 英语不及格同学查询
  • 语文成绩区间筛选
  • 数学成绩特定值查询
  • 模糊匹配查询
  • NULL值处理

5️⃣ 结果排序

  • 基础升序/降序
  • 多字段组合排序

6️⃣ 分页查询

  • LIMIT分页实现

7️⃣ Update - 数据更新

  • 单记录字段更新
  • 批量条件更新

8️⃣ Delete - 数据删除

  • 条件删除
  • 整表清空对比
  • TRUNCATE优化

9️⃣ 插入查询结果

  • 去重数据迁移

🔟 聚合函数

  • COUNT统计
  • SUM/AVG计算
  • MAX/MIN极值

🔟① 分组查询

  • GROUP BY基础
  • HAVING过滤

1. MySQL表的增删查改

表的增删查改简称CRUD:Create(新增)、Retrieve(查找)、Update(修改)、Delete(删除)。这四类操作构成了数据库操作的核心,也是我们日常使用MySQL进行数据管理时最常用的功能。这些操作的对象是对表当中的数据,它们属于典型的DML(Data Manipulation Language)数据操作语言。

CRUD操作贯穿了数据库开发与维护的全过程。无论是业务系统上线初期的数据初始化,还是后续的数据维护、分析与统计,CRUD都是不可或缺的基础。Create操作用于向表中添加新记录,是构建数据仓库的第一步;Retrieve操作则是从数据库中提取数据,是查询和数据分析的核心;Update操作用于调整已有数据的状态,保证数据的准确性;而Delete操作则用于清理无效或冗余的数据,维护数据库的整洁性。

在实际应用中,CRUD操作不仅需要熟练掌握SQL语法,还需要理解其背后的执行逻辑。例如,在插入数据时,如何避免主键或唯一键冲突?在查询数据时,如何高效地筛选出目标记录?在更新或删除数据时,如何精准定位目标记录?这些问题都涉及数据库操作的细节,需要我们在实践中不断积累经验。

此外,CRUD操作的优化也是数据库性能调优的重要方向。例如,频繁的插入操作可能导致数据库性能下降,而高效的查询优化可以显著提升响应速度。因此,深入理解CRUD操作的原理,并结合实际场景进行优化,是提升数据库性能的关键。

接下来,我们将详细介绍CRUD操作的具体实现方式,包括数据插入、查询、修改和删除的SQL语法及其使用场景。通过这些内容的学习,你将掌握如何高效地管理数据库中的数据,并能够根据实际需求灵活运用这些操作。

2. Create

新增数据是数据库操作中最基础的一环,它允许我们向表中添加新的记录。在MySQL中,新增数据主要通过INSERT语句来完成,该语句支持多种不同的插入方式,以满足不同的业务需求。

单行数据 + 全列插入

最基本的插入方式是单行数据全列插入。在这种模式下,我们不需要指定具体的列名,而是按照表中列的默认顺序依次提供所有列的值。例如,假设我们有一个学生表students,其中包含idnameage三个字段,那么插入一条完整记录的方式如下:

INSERT INTO students VALUES (1, '张三', 20);

这里需要注意的是,如果我们没有显式指定列名,那么VALUES后面的值必须严格按照表中列的顺序填写,并且不能遗漏任何一列的值。如果某列允许NULL值或具有默认值,也可以省略不写,但如果不满足这些条件,就会导致插入失败。

多行数据 + 指定列插入

除了单行插入,我们还可以一次性插入多条记录,这样可以减少数据库的交互次数,提高插入效率。此外,在插入数据时,我们也可以选择只插入部分列的数据,而不是所有列。例如,如果我们只想插入nameage两个字段的值,可以使用如下语句:

INSERT INTO students (name, age) VALUES 
('李四', 22),
('王五', 21);

这种方式不仅提高了插入效率,还增强了SQL语句的可读性。在实际开发中,我们通常会根据业务需求选择是否插入所有列或部分列。

插入否则更新

在某些情况下,我们可能会遇到主键或唯一键冲突的问题。例如,当我们尝试插入一条已经存在的记录时,数据库会抛出错误。为了避免这种情况,我们可以使用INSERT ... ON DUPLICATE KEY UPDATE语句。该语句的作用是,如果插入的记录不存在冲突,则直接插入;如果存在冲突,则自动执行更新操作。例如:

INSERT INTO students (id, name, age) VALUES (1, '张三', 20)
ON DUPLICATE KEY UPDATE name = '张三', age = 20;

如果表中已经存在id=1的记录,那么这条SQL语句会自动执行UPDATE部分,更新nameage字段的值。

替换数据

除了插入否则更新,我们还可以使用REPLACE语句来实现类似的效果。REPLACE语句的作用是,如果插入的数据存在主键或唯一键冲突,则先删除冲突的记录,然后再插入新的记录。例如:

REPLACE INTO students (id, name, age) VALUES (1, '张三', 20);

INSERT ... ON DUPLICATE KEY UPDATE不同,REPLACE语句不会直接更新冲突记录的值,而是先删除旧记录,再插入新记录。这意味着,如果表中存在外键约束或其他依赖关系,使用REPLACE可能会带来额外的风险。因此,在实际开发中,我们需要根据具体业务场景选择合适的插入方式。

3. Retrieve

查询数据是数据库操作中最常用的功能之一,它允许我们从表中提取符合特定条件的记录。在MySQL中,查询数据主要通过SELECT语句来完成。该语句支持多种不同的查询方式,以满足不同的业务需求。

全列查询

最基本的查询方式是全列查询,即使用SELECT *语句获取表中的所有列数据。例如,假设我们有一个成绩表scores,其中包含idnamechinesemathenglish五个字段,那么查询所有数据的方式如下:

SELECT * FROM scores;

这种方式的优点是可以一次性获取表中的所有数据,适用于需要查看完整数据的情况。然而,在实际开发中,我们通常不会使用SELECT *进行查询,因为这种方式会返回表中的所有列,增加了网络传输的负担。此外,如果表中存在大量数据,使用SELECT *可能会导致性能下降。因此,在实际开发中,我们通常会选择只查询所需的列。

指定列查询

除了全列查询,我们还可以选择只查询部分列的数据。例如,如果我们只想查询namemath两个字段的值,可以使用如下语句:

SELECT name, math FROM scores;

这种方式不仅减少了网络传输的数据量,还提高了查询效率。在实际开发中,我们通常会根据业务需求选择是否查询所有列或部分列。

查询字段为表达式

除了直接查询表中的列,我们还可以在SELECT语句中使用表达式来计算新的字段值。例如,如果我们想查询每位同学的总成绩,可以使用如下语句:

SELECT name, chinese + math + english AS total_score FROM scores;

这里,chinese + math + english是一个表达式,它计算每位同学的三门成绩之和,并将结果命名为total_score。这种方式适用于需要动态计算新字段的场景。

为查询结果指定别名

在使用表达式查询时,我们通常会给计算出的新字段指定一个别名,以提高查询结果的可读性。例如,在上面的例子中,我们使用AS关键字为总成绩字段指定了别名total_score。除了表达式查询,我们也可以为普通的列指定别名,例如:

SELECT name AS student_name, math AS math_score FROM scores;

这种方式可以让查询结果更加直观,特别是在编写复杂的SQL语句时,合理的别名可以大大提高代码的可读性。

结果去重

在查询数据时,我们可能会遇到重复的记录。例如,如果我们只想查询所有不同的数学成绩,可以使用DISTINCT关键字来去除重复值:

SELECT DISTINCT math FROM scores;

这种方式适用于需要统计不同值的场景。需要注意的是,DISTINCT关键字会对查询结果进行去重,因此在查询大数据量时可能会导致性能下降。

通过上述几种查询方式,我们可以灵活地从表中提取所需的数据,并根据业务需求进行适当的优化。在实际开发中,我们通常会结合使用这些查询方式,以满足不同的数据查询需求。

4. WHERE 条件

在查询数据时,我们通常不会直接查询整个表的所有数据,而是希望筛选出符合特定条件的记录。这时就需要使用WHERE子句来指定查询条件。WHERE子句允许我们根据一个或多个条件来过滤数据,从而得到我们需要的结果。

查询英语不及格的同学及其英语成绩

假设我们想查询英语成绩不及格的同学,即英语成绩小于60分的同学。我们可以使用如下SQL语句:

SELECT name, english FROM scores WHERE english < 60;

这里的WHERE子句指定了筛选条件为english < 60,即英语成绩小于60分。该查询会返回所有符合条件的同学的姓名和英语成绩。

查询语文成绩在80到90分的同学及其语文成绩

如果我们想查询语文成绩在80到90分之间的同学,可以使用WHERE子句结合比较运算符来实现。例如:

SELECT name, chinese FROM scores WHERE chinese >= 80 AND chinese <= 90;

这里我们使用了>=<=运算符来限定语文成绩的范围,并使用AND逻辑运算符来确保同时满足两个条件。

此外,我们还可以使用BETWEEN关键字来简化这个查询:

SELECT name, chinese FROM scores WHERE chinese BETWEEN 80 AND 90;

BETWEEN关键字的作用是匹配某个范围内的值,包括边界值。因此,chinese BETWEEN 80 AND 90等价于chinese >= 80 AND chinese <= 90

查询数学成绩是58或59或98或99分的同学及其数学成绩

如果我们想查询数学成绩是58、59、98或99分的同学,可以使用IN关键字来简化查询。例如:

SELECT name, math FROM scores WHERE math IN (58, 59, 98, 99);

IN关键字的作用是判断某个字段是否在给定的集合中。因此,math IN (58, 59, 98, 99)等价于math = 58 OR math = 59 OR math = 98 OR math = 99

分别查询姓孙的同学和孙某同学

如果我们想查询所有姓孙的同学,可以使用LIKE关键字配合通配符来实现。例如:

SELECT name FROM scores WHERE name LIKE '孙%';

这里的LIKE关键字用于模糊匹配,%是通配符,表示任意数量的字符。因此,name LIKE '孙%'表示匹配所有以“孙”开头的名字。

如果我们想查询名字为“孙某”的同学,即姓孙且名字只有一个字的同学,可以使用如下语句:

SELECT name FROM scores WHERE name LIKE '孙_';

这里的_是通配符,表示任意一个字符。因此,name LIKE '孙_'表示匹配所有以“孙”开头且总长度为2的姓名。

查询语文成绩好于英语成绩的同学

如果我们想查询语文成绩优于英语成绩的同学,可以使用比较运算符来实现。例如:

SELECT name, chinese, english FROM scores WHERE chinese > english;

这里的WHERE子句指定了筛选条件为chinese > english,即语文成绩大于英语成绩。该查询会返回所有符合条件的同学的姓名、语文成绩和英语成绩。

查询总成绩在200分以下的同学

如果我们想查询总成绩低于200分的同学,可以使用表达式查询来计算总成绩,并在WHERE子句中指定筛选条件。例如:

SELECT name, chinese + math + english AS total_score FROM scores WHERE chinese + math + english < 200;

这里的WHERE子句指定了筛选条件为chinese + math + english < 200,即三门成绩之和小于200分。

需要注意的是,在WHERE子句中不能直接使用SELECT中定义的别名,因为WHERE子句的执行顺序早于SELECT语句。因此,我们不能使用如下方式:

SELECT name, chinese + math + english AS total_score FROM scores WHERE total_score < 200; -- 错误

这种写法会导致SQL报错,因为WHERE子句无法识别total_score这个别名。

查询语文成绩大于80分并且不姓孙的同学

如果我们想查询语文成绩大于80分且不姓孙的同学,可以使用NOT关键字来排除姓孙的同学。例如:

SELECT name, chinese FROM scores WHERE chinese > 80 AND name NOT LIKE '孙%';

这里的NOT LIKE '孙%'表示排除所有以“孙”开头的姓名。

查询孙某同学,否则要求总成绩大于200分并且语文成绩小于数学成绩并且英语成绩大于80分

如果我们想查询“孙某”同学,或者总成绩大于200分、语文成绩小于数学成绩、英语成绩大于80分的同学,可以使用逻辑运算符OR来组合多个条件。例如:

SELECT name, chinese, math, english, chinese + math + english AS total_score
FROM scores
WHERE name LIKE '孙_' OR (chinese + math + english > 200 AND chinese < math AND english > 80);

这里的WHERE子句使用了OR逻辑运算符,表示满足任一条件即可。第一个条件是name LIKE '孙_',即名字为“孙某”的同学;第二个条件是chinese + math + english > 200 AND chinese < math AND english > 80,即总成绩大于200分、语文成绩小于数学成绩、英语成绩大于80分的同学。

NULL 的查询

在数据库中,NULL表示未知或缺失的值。在查询数据时,我们可能需要筛选出NULL值或非NULL值。例如,如果我们想查询QQ号已知的同学,可以使用如下语句:

SELECT name, qq FROM students WHERE qq IS NOT NULL;

这里的IS NOT NULL表示筛选出QQ号不为NULL的同学。

如果我们想查询QQ号未知的同学,可以使用如下语句:

SELECT name, qq FROM students WHERE qq IS NULL;

需要注意的是,在判断NULL值时,不能使用=!=运算符,而应该使用IS NULLIS NOT NULL。例如,如下写法是错误的:

SELECT name, qq FROM students WHERE qq = NULL; -- 错误

这是因为NULL表示未知值,使用=运算符无法正确判断NULL值。因此,正确的写法应该是使用IS NULLIS NOT NULL

5. 结果排序

在查询数据时,我们通常希望结果按照某种顺序排列,以便更直观地查看数据。MySQL 提供了 ORDER BY 子句,用于对查询结果进行排序。排序可以是升序(ASC)或降序(DESC),默认情况下为升序。

查询同学及其数学成绩,按数学成绩升序显示

如果我们想查询所有同学的姓名及其数学成绩,并按数学成绩升序排列,可以使用如下 SQL 语句:

SELECT name, math FROM scores ORDER BY math ASC;

这里的 ORDER BY math ASC 表示按照数学成绩升序排序。如果省略 ASCDESC,默认会按照升序排序。

查询同学及其 QQ 号,按 QQ 号排序显示

如果我们想查询同学的姓名及其 QQ 号,并按 QQ 号排序显示,可以使用如下 SQL 语句:

SELECT name, qq FROM students ORDER BY qq;

默认情况下,ORDER BY 会按升序排列。如果想按降序排列,可以使用 DESC 关键字,例如:

SELECT name, qq FROM students ORDER BY qq DESC;

需要注意的是,NULL 值在排序时会被视为比任何值都小。因此,在升序排序时,NULL 值会出现在最前面;在降序排序时,NULL 值会出现在最后面。

查询同学的各门成绩,依次按数学降序、英语升序、语文升序显示

如果我们想查询同学的各门成绩,并按数学成绩降序、英语成绩升序、语文成绩升序排列,可以使用如下 SQL 语句:

SELECT name, math, english, chinese FROM scores 
ORDER BY math DESC, english ASC, chinese ASC;

这里的 ORDER BY 子句指定了多个排序字段,排序优先级与书写顺序相同。也就是说,首先按照数学成绩降序排列,如果数学成绩相同,再按照英语成绩升序排列,如果英语成绩也相同,再按照语文成绩升序排列。

查询同学及其总分,按总分降序显示

如果我们想查询同学的姓名及其总分,并按总分降序排列,可以使用如下 SQL 语句:

SELECT name, chinese + math + english AS total_score FROM scores 
ORDER BY total_score DESC;

这里我们使用了表达式查询来计算每位同学的总分,并为该表达式指定了别名 total_score。在 ORDER BY 子句中,我们可以直接使用该别名进行排序,因为 ORDER BY 的执行顺序在 SELECT 之后。

查询姓孙的同学或姓曹的同学及其数学成绩,按数学成绩降序显示

如果我们想查询姓孙或姓曹的同学,并按数学成绩降序排列,可以使用如下 SQL 语句:

SELECT name, math FROM scores 
WHERE name LIKE '孙%' OR name LIKE '曹%'
ORDER BY math DESC;

这里的 WHERE 子句用于筛选出姓孙或姓曹的同学,ORDER BY math DESC 表示按数学成绩降序排列。

通过 ORDER BY 子句,我们可以灵活地对查询结果进行排序,使数据更加有序、直观。在实际开发中,我们通常会结合 SELECTWHEREORDER BY 来实现更复杂的查询需求。

6. 筛选分页结果

在查询数据时,如果数据量较大,我们通常不会一次性返回所有数据,而是采用分页的方式,每次只返回一部分数据。MySQL 提供了 LIMIT 子句,用于控制查询结果的分页显示。

按 id 进行分页,每页 3 条记录,分别显示第 1、2、3 页

假设我们有一个成绩表 scores,其中包含 idnamechinesemathenglish 五个字段。如果我们想按 id 进行分页,每页显示 3 条记录,可以使用 LIMIT 子句来实现。

查询第 1 页记录

第一页的记录是从第 0 条开始,取 3 条记录:

SELECT * FROM scores ORDER BY id LIMIT 0, 3;

这里的 LIMIT 0, 3 表示从索引为 0 的记录开始,取 3 条记录。

查询第 2 页记录

第二页的记录是从第 3 条开始,取 3 条记录:

SELECT * FROM scores ORDER BY id LIMIT 3, 3;

这里的 LIMIT 3, 3 表示从索引为 3 的记录开始,取 3 条记录。

查询第 3 页记录

第三页的记录是从第 6 条开始,取 3 条记录:

SELECT * FROM scores ORDER BY id LIMIT 6, 3;

这里的 LIMIT 6, 3 表示从索引为 6 的记录开始,取 3 条记录。

需要注意的是,LIMIT 子句的索引是从 0 开始的,因此第一页的起始索引为 0,第二页的起始索引为 3,第三页的起始索引为 6,依此类推。

此外,LIMIT 子句还可以使用另一种写法:

SELECT * FROM scores ORDER BY id LIMIT 3 OFFSET 0; -- 第一页
SELECT * FROM scores ORDER BY id LIMIT 3 OFFSET 3; -- 第二页
SELECT * FROM scores ORDER BY id LIMIT 3 OFFSET 6; -- 第三页

这里的 LIMIT 3 OFFSET s 表示从索引为 s 的记录开始,取 3 条记录。

通过 LIMIT 子句,我们可以灵活地控制查询结果的分页显示,使数据更加有序、直观。在实际开发中,我们通常会结合 ORDER BYLIMIT 来实现分页查询功能。

7. Update

修改数据是数据库操作中的重要环节,它允许我们对已有的记录进行更新,以确保数据的准确性和时效性。在 MySQL 中,修改数据主要通过 UPDATE 语句来完成。该语句允许我们根据特定条件修改表中的数据,并支持多种不同的修改方式。

将孙悟空同学的数学成绩修改为 80 分

假设我们有一个成绩表 scores,其中包含 namemath 等字段。如果我们想将孙悟空的数学成绩修改为 80 分,可以使用如下 SQL 语句:

UPDATE scores SET math = 80 WHERE name = '孙悟空';

这里的 UPDATE 语句指定了要修改的表名 scoresSET 子句指定了要修改的列和新值,WHERE 子句用于定位需要修改的记录。

在执行修改操作之前,我们通常会先查询目标记录的当前值,以确保修改的准确性。例如:

SELECT * FROM scores WHERE name = '孙悟空';

执行上述查询后,我们可以确认孙悟空的数学成绩是否确实需要修改。如果确认无误,再执行 UPDATE 语句进行修改。修改完成后,我们还可以再次执行查询语句,以验证修改是否成功。

将曹孟德同学的数学成绩修改为 60 分,语文成绩修改为 70 分

如果我们想同时修改多个字段的值,可以在 SET 子句中指定多个列的修改。例如,如果我们想将曹孟德的数学成绩修改为 60 分,语文成绩修改为 70 分,可以使用如下 SQL 语句:

UPDATE scores SET math = 60, chinese = 70 WHERE name = '曹孟德';

这里的 SET 子句指定了两个字段的修改,分别是 mathchinese。同样,我们可以在修改前后执行查询语句,以确保修改的准确性。

将总成绩倒数前三的 3 位同学的数学成绩加上 30 分

如果我们想修改多个记录的值,可以结合 ORDER BYLIMIT 子句来实现。例如,如果我们想将总成绩倒数前三的同学的数学成绩加上 30 分,可以使用如下 SQL 语句:

UPDATE scores 
SET math = math + 30 
ORDER BY (chinese + math + english) ASC 
LIMIT 3;

这里的 ORDER BY (chinese + math + english) ASC 表示按照总成绩升序排列,LIMIT 3 表示取前 3 条记录。SET math = math + 30 表示将数学成绩增加 30 分。

需要注意的是,在执行此类操作之前,我们通常会先查询目标记录的当前值,以确保修改的准确性。例如:

SELECT name, chinese + math + english AS total_score 
FROM scores 
ORDER BY total_score ASC 
LIMIT 3;

执行上述查询后,我们可以确认哪些同学的总成绩排名倒数前三。如果确认无误,再执行 UPDATE 语句进行修改。修改完成后,我们还可以再次执行查询语句,以验证修改是否成功。

将所有同学的语文成绩修改为原来的 2 倍

如果我们想修改整张表的某些字段的值,可以省略 WHERE 子句。例如,如果我们想将所有同学的语文成绩修改为原来的 2 倍,可以使用如下 SQL 语句:

UPDATE scores SET chinese = chinese * 2;

这里的 UPDATE 语句没有 WHERE 子句,表示修改整张表的所有记录。SET chinese = chinese * 2 表示将语文成绩乘以 2。

需要注意的是,在执行此类操作之前,我们通常会先查询所有记录的当前值,以确保修改的准确性。例如:

SELECT name, chinese FROM scores;

执行上述查询后,我们可以确认所有同学的语文成绩是否确实需要修改。如果确认无误,再执行 UPDATE 语句进行修改。修改完成后,我们还可以再次执行查询语句,以验证修改是否成功。

通过 UPDATE 语句,我们可以灵活地修改数据库中的数据,确保数据的准确性和时效性。在实际开发中,我们通常会结合 WHEREORDER BYLIMIT 来实现更复杂的修改需求。

8. Delete

删除数据是数据库操作中的重要环节,它允许我们从表中移除不再需要的记录。在 MySQL 中,删除数据主要通过 DELETE 语句来完成。该语句支持多种不同的删除方式,以满足不同的业务需求。

删除孙悟空同学的考试成绩

如果我们想删除某位特定同学的记录,可以在 DELETE 语句中使用 WHERE 子句来指定删除条件。例如,如果我们想删除孙悟空的考试成绩,可以使用如下 SQL 语句:

DELETE FROM scores WHERE name = '孙悟空';

这里的 DELETE FROM 语句指定了要删除的表名 scoresWHERE 子句用于定位需要删除的记录。在执行删除操作之前,我们通常会先查询目标记录的当前值,以确保删除的准确性。例如:

SELECT * FROM scores WHERE name = '孙悟空';

执行上述查询后,我们可以确认孙悟空的考试成绩是否确实需要删除。如果确认无误,再执行 DELETE 语句进行删除。删除完成后,我们还可以再次执行查询语句,以验证删除是否成功。

删除整张表数据

如果我们想删除整张表的所有数据,可以省略 WHERE 子句。例如,如果我们想删除成绩表 scores 中的所有记录,可以使用如下 SQL 语句:

DELETE FROM scores;

这里的 DELETE FROM 语句没有 WHERE 子句,表示删除整张表的所有记录。需要注意的是,这种删除方式不会重置自增长字段的计数器。例如,如果我们删除整张表的数据后再次插入数据,自增长字段的值会继续从删除前的最大值开始递增。

截断表

如果我们想删除整张表的所有数据,并且希望重置自增长字段的计数器,可以使用 TRUNCATE 语句。例如,如果我们想清空成绩表 scores 并重置自增长字段,可以使用如下 SQL 语句:

TRUNCATE TABLE scores;

这里的 TRUNCATE 语句的作用是快速删除整张表的所有数据,并重置自增长字段的计数器。与 DELETE 语句不同,TRUNCATE 不会记录每条删除的记录,因此它的执行速度更快。此外,TRUNCATE 是不可回滚的操作,因此在执行前需要谨慎确认。

通过 DELETETRUNCATE 语句,我们可以灵活地管理数据库中的数据,确保数据的整洁性和准确性。在实际开发中,我们通常会根据具体需求选择合适的删除方式。

9. 插入查询结果

在数据库操作中,除了直接插入数据,我们还可以将查询结果插入到另一张表中。这种方式在数据迁移、数据备份、数据归档等场景中非常有用。MySQL 提供了 INSERT INTO ... SELECT 语句,允许我们将查询结果插入到指定的表中。

删除表中重复的记录,重复的数据只能有一份

在实际应用中,我们可能会遇到表中存在重复记录的问题。例如,假设我们有一个学生表 students,其中包含 idname 两个字段,表中可能存在多个相同姓名的学生记录。如果我们希望删除表中的重复记录,只保留一份数据,可以采取如下步骤:

1. 创建一张临时表

首先,我们需要创建一张临时表,该表的结构与原表相同。可以使用 CREATE TABLE ... LIKE 语句来创建临时表。例如:

CREATE TABLE temp_students LIKE students;

这里的 CREATE TABLE ... LIKE 语句会复制原表的结构,包括列定义、索引等,但不会复制数据。

2. 将去重后的数据插入临时表

接下来,我们可以使用 INSERT INTO ... SELECT DISTINCT 语句,将去重后的数据插入到临时表中。例如:

INSERT INTO temp_students SELECT DISTINCT * FROM students;

这里的 SELECT DISTINCT * 会从原表中查询所有不重复的记录,并将其插入到临时表中。

3. 将原表重命名为其他名字

为了保留原始数据,我们可以将原表重命名为其他名字。例如:

RENAME TABLE students TO old_students;

这里的 RENAME TABLE 语句会将原表重命名为 old_students,以便后续备份或恢复。

4. 将临时表重命名为原表的名字

最后,我们将临时表重命名为原表的名字,以完成去重操作。例如:

RENAME TABLE temp_students TO students;

执行上述操作后,原表 students 中的重复记录已经被删除,只保留了一份数据。临时表 temp_students 被重命名为 students,而原表 students 被重命名为 old_students,以便后续备份或恢复。

通过这种方式,我们可以高效地删除表中的重复记录,确保数据的唯一性和准确性。在实际开发中,我们通常会结合 CREATE TABLE ... LIKEINSERT INTO ... SELECT DISTINCTRENAME TABLE 来实现去重操作。

10. 聚合函数

聚合函数是 SQL 中用于对一组值进行计算并返回单一结果的函数。它们在数据分析和统计中非常有用,例如计算平均值、总和、最大值、最小值等。MySQL 提供了多种常用的聚合函数,包括 COUNTSUMAVGMAXMIN

COUNT 函数

COUNT 函数用于统计表中记录的数量。它可以用于统计所有记录的数量,也可以用于统计某一列中非 NULL 值的数量。

统计班级共有多少同学

假设我们有一个学生表 students,其中包含 idnameage 等字段。如果我们想统计班级中共有多少同学,可以使用如下 SQL 语句:

SELECT COUNT(*) FROM students;

这里的 COUNT(*) 表示统计表中的所有记录数量。

统计班级收集的 QQ 号有多少个

如果我们想统计班级中收集了多少个 QQ 号,可以使用如下 SQL 语句:

SELECT COUNT(qq) FROM students;

这里的 COUNT(qq) 表示统计 qq 列中非 NULL 值的数量。

SUM 函数

SUM 函数用于计算某一列的总和。它通常用于数值类型的列,例如成绩、工资等。

统计本次考试数学成绩的总分

假设我们有一个成绩表 scores,其中包含 idnamechinesemathenglish 等字段。如果我们想统计本次考试的数学总分,可以使用如下 SQL 语句:

SELECT SUM(math) FROM scores;

这里的 SUM(math) 表示计算 math 列的总和。

统计不及格的数学成绩总分

如果我们想统计数学成绩不及格的同学的总分,可以结合 WHERE 子句来实现。例如:

SELECT SUM(math) FROM scores WHERE math < 60;

这里的 WHERE math < 60 表示筛选出数学成绩不及格的同学,然后计算这些同学的数学总分。

AVG 函数

AVG 函数用于计算某一列的平均值。它通常用于数值类型的列,例如成绩、工资等。

统计平均总分

如果我们想统计所有同学的平均总分,可以使用如下 SQL 语句:

SELECT AVG(chinese + math + english) FROM scores;

这里的 AVG(chinese + math + english) 表示计算每位同学的三门成绩之和的平均值。

MAX 函数

MAX 函数用于返回某一列的最大值。它通常用于数值类型的列,例如成绩、工资等。

返回英语最高分

如果我们想查询英语成绩的最高分,可以使用如下 SQL 语句:

SELECT MAX(english) FROM scores;

这里的 MAX(english) 表示返回 english 列的最大值。

MIN 函数

MIN 函数用于返回某一列的最小值。它通常用于数值类型的列,例如成绩、工资等。

返回 70 分以上的英语最低分

如果我们想查询英语成绩在 70 分以上的最低分,可以结合 WHERE 子句来实现。例如:

SELECT MIN(english) FROM scores WHERE english > 70;

这里的 WHERE english > 70 表示筛选出英语成绩大于 70 分的同学,然后返回这些同学的英语最低分。

通过上述聚合函数,我们可以高效地进行数据统计和分析,帮助我们更好地理解和处理数据。在实际开发中,我们通常会结合 SELECTWHERE 和聚合函数来实现各种统计需求。

11. 分组查询

分组查询是 SQL 中用于对数据进行分类统计的重要功能。通过 GROUP BY 子句,我们可以将数据按照指定的列进行分组,并结合聚合函数对每个分组进行统计。分组查询通常用于分析数据的分布情况,例如统计每个部门的平均工资、每个岗位的最低工资等。

显示每个部门的平均工资和最高工资

假设我们有一个员工表 emp,其中包含 deptno(部门编号)、sal(工资)等字段。如果我们想统计每个部门的平均工资和最高工资,可以使用如下 SQL 语句:

SELECT deptno, AVG(sal) AS avg_salary, MAX(sal) AS max_salary
FROM emp
GROUP BY deptno;

这里的 GROUP BY deptno 表示按照部门编号进行分组,AVG(sal) 计算每个部门的平均工资,MAX(sal) 计算每个部门的最高工资。

显示每个部门的每种岗位的平均工资和最低工资

如果我们想进一步细化统计,例如统计每个部门的每种岗位的平均工资和最低工资,可以使用如下 SQL 语句:

SELECT deptno, job, AVG(sal) AS avg_salary, MIN(sal) AS min_salary
FROM emp
GROUP BY deptno, job;

这里的 GROUP BY deptno, job 表示先按照部门编号分组,然后在每个部门内再按照岗位进行分组。AVG(sal) 计算每个分组的平均工资,MIN(sal) 计算每个分组的最低工资。

HAVING 条件

在分组查询中,我们还可以使用 HAVING 子句对分组后的数据进行筛选。与 WHERE 子句不同,HAVING 子句用于筛选分组后的聚合结果,而不是原始数据。

显示平均工资低于 2000 的部门和它的平均工资

如果我们想筛选出平均工资低于 2000 的部门,可以使用如下 SQL 语句:

SELECT deptno, AVG(sal) AS avg_salary
FROM emp
GROUP BY deptno
HAVING avg_salary < 2000;

这里的 HAVING avg_salary < 2000 表示筛选出平均工资小于 2000 的部门。

分组查询的执行顺序

在 SQL 查询中,各个子句的执行顺序如下:

  1. WHERE:先根据 WHERE 子句筛选出符合条件的原始数据。
  2. GROUP BY:根据 GROUP BY 子句对筛选后的数据进行分组。
  3. SELECT:对每个分组执行 SELECT 语句,计算聚合函数的值。
  4. HAVING:根据 HAVING 子句对分组后的结果进行筛选。
  5. ORDER BY:对最终的查询结果进行排序。

通过 GROUP BY 子句和聚合函数的结合使用,我们可以高效地进行数据分类统计,帮助我们更好地理解和分析数据。在实际开发中,我们通常会结合 SELECTGROUP BYHAVINGORDER BY 来实现复杂的分组查询需求。

相关文章:

  • Elasticsearch 读写流程深度解析
  • 相机--相机标定
  • mac安装brew时macos无法信任ruby的解决方法
  • Qt OpenGL 相机实现
  • 无他相机:专业摄影,触手可及
  • 排序算法C语言实现
  • flutter开发安卓APP适配不同尺寸的手机屏幕
  • FreeBSD 14.3 候选版本附带 Docker 镜像和关键修复
  • java28
  • SystemVerilog—new函数的使用和误区
  • 数据结构之堆:解析与应用
  • 数据结构哈希表总结
  • 高阶数据结构——并查集
  • HealthBench医疗AI评估基准:技术路径与核心价值深度分析(上)
  • 光伏功率预测 | BiLSTM多变量单步光伏功率预测(Matlab完整源码和数据)
  • React 核心概念与生态系统
  • Transformer 是未来的技术吗?
  • arc3.2语言sort的时候报错:(sort < `(2 9 3 7 5 1)) 需要写成这种:(sort > (pair (list 3 2)))
  • 【Linux系列】Gunicorn 进程架构解析:主进程与工作进程
  • DAY 43 复习日
  • 福田网站 建设深圳信科/有了域名怎么建网站
  • 时时彩做网站/深圳最新消息
  • 做那种网站/软文网官网
  • 阿里云网站建设部署与发布试题答案/一手渠道推广平台
  • 绵阳建设局官方网站/被国家禁止访问的网站怎么打开
  • 网站建设首页突出什么/整站优化关键词推广