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

MySQL笔记---基本查询

1. 插入数据(增)

INSERT 语句用于向数据库表中插入新记录。基本语法:

INSERT INTO 表名称 [(列1, 列2, ...)] 
VALUES (值1, 值2, ...) [, (值1, 值2, ...)];

我们统一使用这张表进行举例:

-- 创建一张学生表 
DROP TABLE IF EXISTS students;
CREATE TABLE students ( id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, sn INT NOT NULL UNIQUE COMMENT '学号', name VARCHAR(20) NOT NULL, qq VARCHAR(20) 
);

1.1 单行数据 + 全列插入

不指定对哪些列插入数据,此时默认对所有列按照顺序插入:

INSERT INTO 表名称 VALUES (值1, 值2, ...);mysql> INSERT INTO students VALUES (100, 10000, '唐三藏', NULL);
Query OK, 1 row affected (0.01 sec)mysql> INSERT INTO students VALUES (101, 10001, '孙悟空', '1000');
Query OK, 1 row affected (0.00 sec)mysql> SELECT * FROM students;
+-----+-------+-----------+------+
| id  | sn    | name      | qq   |
+-----+-------+-----------+------+
| 100 | 10000 | 唐三藏    | NULL |
| 101 | 10001 | 孙悟空    | 1000 |
+-----+-------+-----------+------+
2 rows in set (0.00 sec)

1.2 多行数据 + 指定列插入

显式指定要对哪些列插入数据(剩下的列使用默认值或自增值):

INSERT INTO 表名称 (列1, 列2, ...) VALUES (值1, 值2, ...) [, (值1, 值2, ...)];mysql> INSERT INTO students (id, sn, name) VALUES -> (102, 20001, '曹孟德'), -> (103, 20002, '孙仲谋');
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0mysql> SELECT * FROM students;
+-----+-------+-----------+------+
| id  | sn    | name      | qq   |
+-----+-------+-----------+------+
| 100 | 10000 | 唐三藏    | NULL |
| 101 | 10001 | 孙悟空    | 1000 |
| 102 | 20001 | 曹孟德    | NULL |
| 103 | 20002 | 孙仲谋    | NULL |
+-----+-------+-----------+------+
4 rows in set (0.00 sec)

1.3 冲突则更新

如果插入的数据与已存在的数据发生冲突(主键,唯一键等):

mysql> INSERT INTO students (id, sn, name) VALUES (100, 10010, '唐大师');
ERROR 1062 (23000): Duplicate entry '100' for key 'students.PRIMARY'
mysql> INSERT INTO students (sn, name) VALUES (20001, '曹阿瞒');
ERROR 1062 (23000): Duplicate entry '20001' for key 'students.sn'

我们可以采用冲突则更新的方式进行插入:

INSERT INTO 表名称 [(列1, 列2, ...)]
VALUES (值1, 值2, ...)
ON DUPLICATE KEY UPDATE 列 = 值 [, 列 = 值]
-- ON DUPLICATE KEY 当发生重复key的时候

即,若发生冲突,则不进行插入,而是对被冲突的数据进行更新:

mysql> INSERT INTO students (id, sn, name) VALUES (100, 10010, '唐大师') -> ON DUPLICATE KEY UPDATE sn = 10010, name = '唐大师';
Query OK, 2 rows affected (0.01 sec)mysql> SELECT * FROM students;
+-----+-------+-----------+------+
| id  | sn    | name      | qq   |
+-----+-------+-----------+------+
| 100 | 10010 | 唐大师    | NULL |
| 101 | 10001 | 孙悟空    | 1000 |
| 102 | 20001 | 曹孟德    | NULL |
| 103 | 20002 | 孙仲谋    | NULL |
+-----+-------+-----------+------+
4 rows in set (0.00 sec)

当我们执行插入语句之后,可以看到执行的反馈提示两行受到影响,当采用如上方式进行插入时,受影响行数有三种情况:

  • 0 row affected: 表中有冲突数据,但冲突数据的值和 update 的值相等;
  • 1 row affected: 表中没有冲突数据,数据被插入 ;
  • 2 row affected: 表中有冲突数据,并且数据已经被更新。

除了执行后的输出结果,我们还可以通过ROW_COUNT()函数查询最近一次受影响行数:

mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|          -1 |
+-------------+
1 row in set (0.00 sec)

1.4 替换

除了用INSERT进行插入,我们还可以使用REPALCE进行插入:

REPLACE INTO 表名称 [(列1, 列2, ...)] 
VALUES (值1, 值2, ...) [, (值1, 值2, ...)];

相比于INSERT,REPLACE关键字进行插入的行为是:

  • 不冲突:直接插入(1 row affected);
  • 冲突:删除冲突的数据,再重新插入(2 row affected)。
mysql> REPLACE INTO students (sn, name) VALUES (20001, '曹阿瞒');
Query OK, 2 rows affected (0.01 sec)mysql> SELECT * FROM students;
+-----+-------+-----------+------+
| id  | sn    | name      | qq   |
+-----+-------+-----------+------+
| 100 | 10010 | 唐大师    | NULL |
| 101 | 10001 | 孙悟空    | 1000 |
| 103 | 20002 | 孙仲谋    | NULL |
| 105 | 20001 | 曹阿瞒    | NULL |
+-----+-------+-----------+------+
4 rows in set (0.00 sec)

1.5 插入查询结果

可以将查询的结果插入到表中:

INSERT INTO 表名称 SELECT ...

要求查询出来的临时表每一行的属性与目标表每一行的属性完全对应,否则无法插入。

2. 查询数据(查)

SELECT 语句是用于从数据库表中查询和检索数据的核心语句,也是 SQL 中最常用、功能最灵活的语句之一。它支持从单表、多表关联,到复杂的条件过滤、排序、聚合统计等多种需求。

2.1 基本语法结构

SELECT 语句的核心语法遵循固定顺序(执行顺序与书写顺序不同,但书写需严格按此顺序):

SELECT [DISTINCT] 列名1, 列名2, ...      -- (4)要查询的列(或*表示所有列)
FROM 表名称1 [JOIN 表名称2 ON 关联条件]   -- (1)数据来源(单表或多表关联)
WHERE 行过滤条件                         -- (2)筛选符合条件的行(先过滤行,再处理列)
GROUP BY 分组列1, 分组列2, ...            -- (3)按指定列分组(用于聚合统计)
HAVING 分组过滤条件                      -- (5)筛选分组后的结果(仅对分组有效)
ORDER BY 排序列1 [ASC/DESC], ...         -- (6)对结果排序(ASC升序,DESC降序,默认ASC)
LIMIT [偏移量,] 行数                      -- (7)限制返回的结果条数(用于分页等场景)

为了方便举例,我们再创建一个表格:

-- 创建表结构 
CREATE TABLE exam_result ( id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20) NOT NULL COMMENT '同学姓名', chinese float DEFAULT 0.0 COMMENT '语文成绩', math float DEFAULT 0.0 COMMENT '数学成绩', english float DEFAULT 0.0 COMMENT '英语成绩' 
);-- 插入测试数据 
INSERT INTO exam_result (name, chinese, math, english) VALUES ('唐三藏', 67, 98, 56), ('孙悟空', 87, 78, 77), ('猪悟能', 88, 98, 90), ('曹孟德', 82, 84, 67), ('刘玄德', 55, 85, 45), ('孙权', 70, 73, 78), ('宋公明', 75, 65, 30);mysql> SELECT * FROM exam_result;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  1 | 唐三藏    |      67 |   98 |      56 |
|  2 | 孙悟空    |      87 |   78 |      77 |
|  3 | 猪悟能    |      88 |   98 |      90 |
|  4 | 曹孟德    |      82 |   84 |      67 |
|  5 | 刘玄德    |      55 |   85 |      45 |
|  6 | 孙权      |      70 |   73 |      78 |
|  7 | 宋公明    |      75 |   65 |      30 |
+----+-----------+---------+------+---------+
7 rows in set (0.01 sec)

2.2 基本查询

-- 查询指定表的所有列
SELECT * FROM 表名称;-- 查询指定表的指定列
SELECT 列名1, 列名2, ... FROM 表名称;mysql> SELECT name, chinese FROM exam_result;
+-----------+---------+
| name      | chinese |
+-----------+---------+
| 唐三藏    |      67 |
| 孙悟空    |      87 |
| 猪悟能    |      88 |
| 曹孟德    |      82 |
| 刘玄德    |      55 |
| 孙权      |      70 |
| 宋公明    |      75 |
+-----------+---------+
7 rows in set (0.00 sec)
2.2.1 去重查询

在SELECT关键字后加上DISTINCT关键字,此时查询出来的结果就不会有重复行:

-- 去重查询指定表的所有列
SELECT DISTINCT * FROM 表名称;-- 去重查询指定表的指定列
SELECT DISTINCT 列名1, 列名2, ... FROM 表名称;
2.2.2 列重命名

被查询的列可以是表达式,例如:

mysql> SELECT name, chinese+math+english FROM exam_result;
+-----------+----------------------+
| name      | chinese+math+english |
+-----------+----------------------+
| 唐三藏    |                  221 |
| 孙悟空    |                  242 |
| 猪悟能    |                  276 |
| 曹孟德    |                  233 |
| 刘玄德    |                  185 |
| 孙权      |                  221 |
| 宋公明    |                  170 |
+-----------+----------------------+
7 rows in set (0.00 sec)

但是这样的表达式显然可读性较低,我们可以对要查询的列进行重命名:

SELECT DISTINCT 列名1 AS 新列名1, 列名2 AS 新列名2, ... FROM 表名称;
或者 
SELECT DISTINCT 列名1 新列名1, 列名2 新列名2, ... FROM 表名称;mysql> SELECT name AS 姓名, chinese+math+english AS 总分 FROM exam_result;
+-----------+--------+
| 姓名      | 总分   |
+-----------+--------+
| 唐三藏    |    221 |
| 孙悟空    |    242 |
| 猪悟能    |    276 |
| 曹孟德    |    233 |
| 刘玄德    |    185 |
| 孙权      |    221 |
| 宋公明    |    170 |
+-----------+--------+
7 rows in set (0.00 sec)

2.3 条件过滤(WHERE)

对被查询的表中的记录(行)进行筛选:

WHERE 条件表达式
2.3.1 比较表达式

比较表达式通过 比较运算符 对两个值(或表达式)进行比较,返回 TRUE(1)、FALSE(0)或 NULL(无法判断,如与 NULL 比较)。

常用于 WHERE 子句筛选行,或 SELECT 子句计算列值。

常用比较运算符及示例
运算符作用说明适用场景
=等于(注意:不能判断 NULL)精确匹配
<> 或 !=不等于排除特定值
> / <大于 / 小于范围筛选(单侧)
>= / <=大于等于 / 小于等于范围筛选(包含边界)
BETWEEN A AND B在 A 到 B 之间(包含 A 和 B)连续范围筛选
IN (值1, 值2, ...)在指定集合中离散值匹配
NOT IN (...)不在指定集合中排除离散值
LIKE模糊匹配(% 匹配任意字符,_ 匹配单个字符)字符串模糊查询
NOT LIKE不满足模糊匹配排除模糊匹配结果
REGEXP / RLIKE正则表达式匹配复杂字符串模式匹配
IS NULL判断值是否为 NULL筛选NULL
IS NOT NULL判断值是否不为 NULL筛选非NULL
2.3.2 逻辑表达式(组合多个条件)

逻辑表达式通过 逻辑运算符 组合多个比较表达式,最终返回 TRUE/FALSE/NULL,用于处理 “多条件同时满足” 或 “满足任一条件” 的场景。

常用逻辑运算符及优先级
运算符作用优先级
NOT逻辑非(否定条件)最高
AND逻辑与(同时满足)中等
OR逻辑或(满足任一)最低

注意:

  • 逻辑运算符优先级:NOT > AND > OR;
  • 如需改变优先级,用 括号 () 强制指定计算顺序。
2.3.3 示例

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

mysql> SELECT name, english FROM exam_result WHERE english < 60;
+-----------+---------+
| name      | english |
+-----------+---------+
| 唐三藏    |      56 |
| 刘玄德    |      45 |
| 宋公明    |      30 |
+-----------+---------+
3 rows in set (0.00 sec)

(2)查询语文成绩在 [80, 90] 分的同学及其语文成绩

mysql> SELECT name, chinese FROM exam_result WHERE chinese BETWEEN 80 AND 90;
+-----------+---------+
| name      | chinese |
+-----------+---------+
| 孙悟空    |      87 |
| 猪悟能    |      88 |
| 曹孟德    |      82 |
+-----------+---------+
3 rows in set (0.00 sec)

(3)查询姓孙的同学

mysql> SELECT name FROM exam_result WHERE name LIKE '孙%';
+-----------+
| name      |
+-----------+
| 孙悟空    |
| 孙权      |
+-----------+
2 rows in set (0.00 sec)

(4)查询孙某同学

mysql> SELECT name FROM exam_result WHERE name LIKE '孙_';
+--------+
| name   |
+--------+
| 孙权   |
+--------+
1 row in set (0.00 sec)

(5)查询qq号不为空的的同学及其qq号

mysql> SELECT name, qq FROM students WHERE qq IS NOT NULL;
+-----------+------+
| name      | qq   |
+-----------+------+
| 孙悟空    | 1000 |
+-----------+------+
1 row in set (0.00 sec)

2.4 排序(ORDER BY)

ORDER BY 用于对查询结果按指定列排序,默认按 ASC(升序)排列,可指定 DESC(降序)

ORDER BY 列1 [ASC/DESC] [, 列2 [ASC/DESC]]...

默认情况下使用升序排序。

2.4.1 示例

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

mysql> SELECT name, math FROM exam_result ORDER BY math;
+-----------+------+
| name      | math |
+-----------+------+
| 宋公明    |   65 |
| 孙权      |   73 |
| 孙悟空    |   78 |
| 曹孟德    |   84 |
| 刘玄德    |   85 |
| 唐三藏    |   98 |
| 猪悟能    |   98 |
+-----------+------+
7 rows in set (0.00 sec)

(2)查询同学的各门成绩,依次按照数学降序,英语升序,语文升序的方式显示

mysql> SELECT name, math, chinese, english FROM exam_result ORDER BY math DESC, chinese ASC, english ASC;
+-----------+------+---------+---------+
| name      | math | chinese | english |
+-----------+------+---------+---------+
| 唐三藏    |   98 |      67 |      56 |
| 猪悟能    |   98 |      88 |      90 |
| 刘玄德    |   85 |      55 |      45 |
| 曹孟德    |   84 |      82 |      67 |
| 孙悟空    |   78 |      87 |      77 |
| 孙权      |   73 |      70 |      78 |
| 宋公明    |   65 |      75 |      30 |
+-----------+------+---------+---------+
7 rows in set (0.00 sec)

2.5 限制结果条数(LIMIT)

LIMIT 用于限制返回的结果行数,常用于分页查询(如 “每页显示 10 条数据”),语法有三种:

  1. LIMIT 行数:直接返回前 N 行
    LIMIT 行数
  2. LIMIT 偏移量, 行数:从 “偏移量” 位置开始,返回 N 行(偏移量从 0 开始)
    LIMIT 偏移量, 行数
  3. LIMIT 行数 OFFSET 偏移量:从 “偏移量” 位置开始,返回 N 行(偏移量从 0 开始)
    LIMIT 行数 OFFSET 偏移量
2.5.1 示例

(1)查询总分排名前三的同学

mysql> SELECT name, math+chinese+english 总分 FROM exam_result ORDER BY 总分 DESC LIMIT 3;
+-----------+--------+
| name      | 总分   |
+-----------+--------+
| 猪悟能    |    276 |
| 孙悟空    |    242 |
| 曹孟德    |    233 |
+-----------+--------+
3 rows in set (0.00 sec)

(2)查询总分排行次三名的同学

mysql> SELECT name, math+chinese+english 总分 FROM exam_result ORDER BY 总分 DESC LIMIT 3, 3;
+-----------+--------+
| name      | 总分   |
+-----------+--------+
| 唐三藏    |    221 |
| 孙权      |    221 |
| 刘玄德    |    185 |
+-----------+--------+
3 rows in set (0.00 sec)mysql> SELECT name, math+chinese+english 总分 FROM exam_result ORDER BY 总分 DESC LIMIT 3 OFFSET 3;
+-----------+--------+
| name      | 总分   |
+-----------+--------+
| 唐三藏    |    221 |
| 孙权      |    221 |
| 刘玄德    |    185 |
+-----------+--------+
3 rows in set (0.00 sec)

2.6 聚合统计(GROUP BY + 聚合函数)

当需要对数据进行 “统计分析”(如计数、求和、平均值)时,需结合 聚合函数GROUP BY 分组。

2.6.1 聚合函数

用于对一组数据进行统计计算(常与 GROUP BY 配合使用)。

函数作用
COUNT(*)统计行数(包含 NULL)
COUNT(列名)统计指定列非 NULL 的行数
SUM(列名)计算指定列的总和(仅数值型)
AVG(列名)计算指定列的平均值
MAX(列名)取指定列的最大值
MIN(列名)取指定列的最小值

聚合函数在不进行分组时,就是对整个表生效。如果使用GROUP BY子句进行分组的话,就是每个组单独统计。

使用聚合函数作为表的查询结果时,表自身的列不能作为查询结果(聚合函数是多行统计的结果,各行之间的列有所不同)。

示例:查询各科平均分

mysql> SELECT AVG(chinese) 语文平均分, AVG(math) 数学平均分, AVG(english) 英语平均分 FROM exam_result;
+-------------------+-----------------+--------------------+
| 语文平均分         | 数学平均分       | 英语平均分          |
+-------------------+-----------------+--------------------+
| 74.85714285714286 |              83 | 63.285714285714285 |
+-------------------+-----------------+--------------------+
1 row in set (0.00 sec)
2.6.2 GROUP BY 分组统计
GROUP BY 列名 [, 列名]...

GROUP BY 按指定列分组(该列值相同的分为一组),聚合函数会作用于每个分组(而非整个表)。

GROUP BY 子句之后出现的列(用于分组的列),都可以作为查询结果(每一个组,这些列都是相同的)。

我们为exam_result新增一列class,并将同学们按照语文分数分为两个班:

mysql> SELECT * FROM exam_result;
+----+-------+-----------+---------+------+---------+
| id | class | name      | chinese | math | english |
+----+-------+-----------+---------+------+---------+
|  1 |    01 | 唐三藏    |      67 |   98 |      56 |
|  2 |    02 | 孙悟空    |      87 |   78 |      77 |
|  3 |    02 | 猪悟能    |      88 |   98 |      90 |
|  4 |    02 | 曹孟德    |      82 |   84 |      67 |
|  5 |    01 | 刘玄德    |      55 |   85 |      45 |
|  6 |    01 | 孙权      |      70 |   73 |      78 |
|  7 |    01 | 宋公明    |      75 |   65 |      30 |
+----+-------+-----------+---------+------+---------+
7 rows in set (0.00 sec)

示例:分别查询两个班的平均值

mysql> SELECT class, AVG(chinese) 语文平均分, AVG(math) 数学平均分, AVG(english) 英语平均分 FROM exam_result GROUP BY class;
+-------+-------------------+-------------------+-----------------+
| class | 语文平均分        | 数学平均分        | 英语平均分      |
+-------+-------------------+-------------------+-----------------+
|    01 |             66.75 |             80.25 |           52.25 |
|    02 | 85.66666666666667 | 86.66666666666667 |              78 |
+-------+-------------------+-------------------+-----------------+
2 rows in set (0.00 sec)
2.6.3 HAVING 过滤分组结果

WHERE 过滤的是 “行”,HAVING 过滤的是 “分组后的结果”(仅在 GROUP BY 后使用)。

HAVING 条件表达式

示例:查询语文平均分大于80的班级及其平均分

mysql> SELECT class, AVG(chinese) 语文平均分 FROM exam_result GROUP BY class HAVING 语文平均分 > 80;
+-------+-------------------+
| class | 语文平均分        |
+-------+-------------------+
|    02 | 85.66666666666667 |
+-------+-------------------+
1 row in set (0.00 sec)

2.7 子查询(嵌套查询)

子查询是指 “在一个 SELECT 语句中嵌套另一个 SELECT 语句”,内层查询的结果作为外层查询的条件或数据源。

2.7.1 示例

(1)查询数学成绩大于平均分的同学及其成绩

mysql> SELECT name, math FROM exam_result WHERE math > (SELECT AVG(math) FROM exam_result);
+-----------+------+
| name      | math |
+-----------+------+
| 唐三藏    |   98 |
| 猪悟能    |   98 |
| 曹孟德    |   84 |
| 刘玄德    |   85 |
+-----------+------+
4 rows in set (0.00 sec)

(2)查询在students表中出现的同学及其成绩

mysql> SELECT name, math, chinese, english FROM exam_result WHERE name IN (SELECT name FROM students);
+-----------+------+---------+---------+
| name      | math | chinese | english |
+-----------+------+---------+---------+
| 孙悟空    |   78 |      87 |      77 |
+-----------+------+---------+---------+
1 row in set (0.00 sec)

3. 删除数据(删)

3.1 DELETE语句

DELETE 语句用于从表中删除符合条件的记录,是数据维护中常用的操作。由于删除操作不可逆(除非有备份或事务回滚),使用时需格外谨慎。基本语法:

DELETE FROM 表名 [WHERE 条件];  -- 若省略WHERE则删除表中所有记录

3.2 TRUNCATE语句

TRUNCATE 语句用于清空表的内容。基本语法:

TRUNCATE [TABLE] 表名;

准确来说是重置表,表的所有参数回到刚创建的状态。

3.3 清空表的两种方式对比

DELETE FROM 表名:逐行删除记录,会记录事务日志(可回滚),不重置自增主键(如自增 ID 会继续从上次的值增长);

TRUNCATE TABLE 表名:直接清空表数据(类似 “删除表再重建”),速度更快不记录日志(不可回滚),会重置自增主键。

4. 更新数据(改)

UPDATE 语句用于修改表中已存在的记录,是数据维护的核心操作之一。

它支持单表更新、多表关联更新,还能结合条件、函数或子查询实现复杂的更新逻辑。由于更新操作不可逆(除非有备份或事务回滚),使用时需格外注意条件的准确性。基本语法:

UPDATE 表名
SET 列1 = 值1, 列2 = 值2, ...  -- 要更新的列及对应新值
[WHERE 条件];  -- 可选,筛选需要更新的记录(省略则更新表中所有记录)
http://www.dtcms.com/a/424576.html

相关文章:

  • 珠宝网站建设方案网站建设gzzhixun
  • 秦皇岛建设网站公司个人免费网站建设模板
  • 五指山住房建设局网站wordpress 新浪微博登入
  • 网站备案准备资料wordpress手机底部联系插件
  • 网站建设有几大板块做关键字要改网站
  • 上海有名的网站建设公司有哪些wordpress 要加上
  • 辽宁网站备案要多久电子简历模板
  • 国产32位MO+内核MCU主频24MhzPY32F002B开发板
  • 仿qq网站程序温州市住房和城乡建设厅网站首页
  • LLM模型kv cache的估计和应用
  • 铁岭市网站建设公司重庆森林经典台词图片
  • 【开题答辩全过程】以 PHP茶叶同城配送网站的设计与实现为例,包含答辩的问题和答案
  • 自建站服务专业建网站设计公司
  • 做网站需要哪一些内容益阳建站网站制作
  • 前端开发工具都有哪些?常用前端开发工具清单与场景化推荐
  • Apifox新版本重磅升级!AI用例生成+多模块优化!
  • 深圳网站建设公司jm3q新网站备案查询
  • 智能锁网站建设关键词宜春专业的企业网站建设公司
  • 深入理解 SPI:从定义到 Spring Boot 实践
  • 麒麟区住房和城乡建设局网站桂林北站是高铁站吗
  • 彩虹表(还原函数)
  • 查表型状态机
  • 可控可信的工业界 Agent 方案研究 - parlant
  • 徐州设计网站长沙计算机培训机构排名前十
  • flink api-datastream api-sink算子
  • 有没有专门做衣服搭配的网站怎样在织梦后台里面做网站地图
  • 【go】普通map和sync.map的区别,源码解析
  • wordpress多站点详细设置(图解)建个个人网站一年多少钱
  • Python bisect
  • Docker 安装与核心知识总结