MySQL SQL语句

MySQL SQL语句

1
2
3
4
5
中文   英文对应(CRUD)  SQL命令       作用
增         create        INSERT       往表中添加新的数据行
删         delete       DELETE       移除表中的数据
改         update       UPDATE       修改表中已存在的数据
read         SELECT       从表种检索数据
1
2
3
4
5
6
7
8
9
(Create)- INSERT

INSERT INTO 表名 (列1,列2) VALUES (值1,值2);
·如果是字符串(比如名字),需要用单引号''包起来
·如果是数字(比如分数),直接写就好
SQL需要先知道你要往那些“列”填数据,然后再告诉它具体的“值”是什么
例1:如果想往student_scores表里添加一个名叫'张三',分数为90的学生,怎么写SQL语句?
  INSERT INTO student_scores (name,score) VALUES ('张三',90);
  
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
(Read)-SELECT

SELECT 你想要的列 FROM 表名;
· *:这个*就是一个通配符,告诉数据库:“我不挑,把这个表里的列全给我拿出来!”

SELECT * FROM 表明 WHERE 列名 =;

例1:利用WHERE子句,写一条SQL语句,只把'张三'这一行数据查出来
SELECT * FROM student_scores WHERE name = '张三';


排序
SELECT * FROM 表名 ORDER BY 列名 排序规则;

· 排序规则有两种:
 · ASC:升序,从小到大(默认就是这个,可以不写也行)
 · DESC:降序,从大到小
 
 例2:我们要打印一份成绩单排名表,要求分数从高到低排列,写出这条SQL语句
 SELECT * FROM student_scores ORDER BY score DESC;
 
限制数量
 
 SELECT * FROM 表名 LIMIT 数量;
 
 例3:写一条SQL,只显示分数最高的3位
 
 SELECT * FORM student_scores ORDER BY score DESC LIMIT 3;
 · ORDER BY score DESC:先把所有同学按分数从高到低排好队

模糊查询 LIKE
有时候我们查询某一类数据,记不起来具体数据,这个时候,我们可以不用管=号,我们可以直接用LIKE操作符,同时也可以配合LIKE使用的百分号%,它%代表“任意多个字符”

例4:查找出所有姓“张”的同学
SELECT * FROM student_scores WHERE name LIKE '张%'

分组
GROUP BY的作用就是把原本散乱的每一行数据,按照你指定的列,“捏”在一起

SELECT 类别列,聚合函数(统计列)
FROM 表名
GROUP BY 类别列;

例5:算出每个班级的平均数
SELECT class,AVG(score) FROM student_scores GROUP BY class;

分组后的过滤(HAVING)
SELECT 类别列,聚合函数(统计列)
FROM 表名
GROUP BY 类别列
HAVING 聚合函数(统计列)> 值;

凡是表里本来就有列,用WHERE筛;凡是后来算出来的结果(比如平均数、总数),用HAVING筛。
例6:只显示平均分(AVG(score))大于85的班级
SELECT class,AVG(score)FROM student_scores GROUP BY class HAVING AVG(score) > 85;


多表查询
INNER JOIN (内连接)
INNER JOIN就像把两张表拿来对暗号,只有当两张表的关联字段能对上号时,它才会把这一行数据拼在一起。

SELECT 表1.列名,表2.列名
FROM 表1
INNER JOIN 表2
ON 表1.关联列 = 表2.关联列;

例7:将 students 表和 classes 表连接起来。 关联条件是:students 表的 class_id 等于 classes 表的 id。 我们需要查询的结果是:students.name 和 classes.teacher

SELECT students.name,classes.teacher FROM students INNER JOIN classes ON students.class_id = classes.id;

左连接(LEFT JOIN)
左边的表(主表)最大,不管右边有没有对应的,左边的都要全部显示出来

SELECT students.name, classes.teacher
FROM students  -- 👈 这是左表
LEFT JOIN classes -- 👉 这是右表
ON students.class_id = classes.id;

例8:请你直接复制上面的语法思路,写出这条 LEFT JOIN 语句。 想一想,查询结果里,'小明' 的 teacher 那一栏会显示什么?(可以猜一下)

在数据库中,如果没有找到匹配的数据,该位置就会显示为 NULL(空值)
1
2
3
4
5
6
7
改(Update)- UPDATE

UPDATE 表名 SET 要修改的列 = 新值 WHERE 条件列 = 某值;

例1:帮'张三'该分数,写一条SQL语句,将student_scores表中,命令是'张三'的那一行,score修改为95

UPDATE student_scores SET score = 95 WHERE name = '张三'
1
2
3
4
5
6
7
(Delete)- DELETE

DELETE FROM 表名 WHERE 条件列 = 某值;

例1:写一条SQL语句,安全地将'李四'从student_scores表中删除

DELETE FROM student_scores WHERE name = '李四'
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

建表
在 SQL 中,创建新表使用 CREATE TABLE 命令。这就好比你在 Excel 里新建一个 Sheet,并且规定好每一列叫什么名字,只能填什么类型的数据。

第一步:认识“原材料” (数据类型)
在造表之前,你必须告诉数据库,每一列将来要存什么样的数据。MySQL 里最常用的三种类型是:
INT:整数。用来存 ID、年龄、数量。(例如:101, 25)
VARCHAR(n):可变长度字符串。用来存名字、邮箱、地址。
n 代表最大长度。比如 VARCHAR(50) 意思是最多存 50 个字符。
DATE:日期。用来存生日、入职时间。(例如:'2023-01-01'
第二步:确立“身份证” (主键 PRIMARY KEY) 🔑
这是建表时最重要的概念!
每一张表最好都有一个主键 (Primary Key)。它是每一行数据的唯一标识符。
就像每个公民都有唯一的身份证号。
规则:主键的值不能重复,也不能为空。
通常我们会把 id 列设为主键。



CREATE TABLE 表名 (
    列名1 数据类型,
    列名2 数据类型,
    ...
    PRIMARY KEY (主键列名)
);



例1:请你设计一张全新的 students 表,要求包含以下三列:
id:类型是 INT(这是主键!)。
name:类型是 VARCHAR(50)(名字最长 50 个字足够了)。
age:类型是 INT。
请尝试写出完整的 SQL 语句! (提示:注意括号的位置,最后别忘了分号)
CREATE TABLE students (  id INT, name VARCHAR(50), age INT, PRIMARY KEY (id) );



例2:设计 teachers 表
现在请你利用这两个新武器,设计一张更完美的 teachers (教师表)要求:
id:类型 INT,不仅是 主键,还要能 自动增长 (AUTO_INCREMENT)name:类型 VARCHAR(30),并且 不允许为空 (NOT NULL)subject (科目):类型 VARCHAR(20),这个允许为空(可能刚入职还没定教啥)。

列名 数据类型 NOT NULL AUTO_INCREMENT
(注意:AUTO_INCREMENT通常只用于主键)

CREATE TABLE teachers (
    id INT AUTO_INCREMENT,      -- 1. id 是整数,且自动增长
    name VARCHAR(30) NOT NULL,  -- 2. name 是字符串,且不能为空
    subject VARCHAR(20),        -- 3. subject 是字符串,允许为空(默认)
    PRIMARY KEY (id)            -- 4. 指定 id 为主键
);


删表
DROP TABLE 表名;

例3:假设刚才建立的 students 表设计得不好,我们要把它删掉重来。 请写出删除 students 表的语句。
DROP TABLE students;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
创建索引
索引就相当于字段的目录
注意:索引也是数据,需要占用硬盘空间,当你INSERT、UPDATE、DELETE数据时,数据库不仅要修改原数据,还要去修改所有的索引目录,索引越多,写入速度越慢。
只给经常出现在WHERE 后面的列,或者经常用来排序(ORDER BY)的列加索引。
例假设我们的 students 表里有 100 万 个学生。校长经常查某个名字,比如:
SELECT * FROM students WHERE name = '张三';
如果没有多因,数据库会把100万行全都看一遍

优化方案:给name列加一个索引
CREATE INDEX 索引名 ON 表名 (列名);
(注意:索引名通常以idx_开头,方便识别)

例1:为 students 表的 name 列创建一个索引,索引名字叫 idx_name
CREATE INDEX idx_name ON students (name);

删除索引
DROP INDEX 索引名 ON 表名;
例2:删除 students 表上的 idx_name 索引
DROP INDEX idx_name ON students;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
加装(ADD)

ALTER TABLE 表名 ADD 新列名 数据类型;
例1:给 students 表新增一列 gender,数据类型是 VARCHAR(4)(存“男”或“女”足够了)
ALTER TABLE students ADD gender VARCHAR(4);

改造(MODIFY)
ALTER TABLE 表名 MODIFY 列名 新的数据类型;

例2:将 students 表的 name 列修改为 VARCHAR(100),让它能容纳更长的名字
ALTER TABLE students MODIFY name VARCHAR(100);

拆除(DROP)
ALTER TABLE 表名 DROP COLUMN 列名;
例3:请写一条 SQL 语句,从 students 表中彻底删除 age 这一列
ALTER TABLE students DROP COLUMN age;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
逻辑执行顺序:
先执行括号里的(内层查询),再执行(外面查询)

标量子查询(返回一个值)
例1:假设我们有一张 products (商品表),里面有 name (商品名) 和 price (价格)任务: 请写一条 SQL 语句,找出所有 价格高于“电视机” 的商品。

提示思路:
我不知道“电视机”多少钱,所以要先查电视机的价格:(SELECT price FROM products WHERE name = '电视机')把这个括号放到 WHERE 后面去比较。

SELECT * FROM products
WHERE price > (SELECT price FROM products WHERE name = '电视机');


#2:列表子查询 (IN)

刚才那个例子,内层查询只返回了一个数字(电视机的价格)。
但如果内层查询返回了一堆数据,怎么办?

我们要找出所有属于“艺术系”的学生。
我们有两张表:

1. students:(id, name, class\_id)
2. classes:(id, department)

思路:
1.内层:先从 classes 表里,找出所有属于 '艺术系'的班级 ID。(可能有好几个班,比如 101, 102, 105...)
2.外层:在 students表里,找出class_id在这个列表里的学生。

这时候,不能用 `=`(等于),因为等于号一次只能对一个数。
我们要用 IN(在...里面)。

语法结构:

SELECT ... FROM ...
WHERE 关联列 IN (SELECT 关联列 FROM ... WHERE ...);


例2:请写出查询语句,找出 `class_id` 属于 (从 classes 表查出的 '艺术系' 的 id) 的所有学生姓名。
(提示:外层查 students,内层查 classes)
SELECT * FROM students
WHERE class_id IN (
    SELECT id             -- 1. 我们要把班级的 ID 拿出来
    FROM classes
    WHERE department = '艺术系' -- 2. 筛选条件是部门名称
);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
安全锁 (Foreign Keys) 

场景危机:
想象一下,如果有粗心的员工往 students表里录入了一个学生,填写的 class_id是 999。
可是!classes表里根本就没有 999 班!

  * 这就叫 “脏数据”
  * 如果这种数据多了,你的JOIN查询就会失效(因为连不上),报表就会出错。

解决方案:外键约束 (FOREIGN KEY)
外键就像一条无形的链子,把 students表的class_id牢牢地锁在classes表的id上。
  * 规则:你想在students表里填 class_id?可以,但你填的这个数字,必须是classes表里已经存在的id。否则,数据库直接报错,拒绝录入!

语法结构(在建表时使用)

CREATE TABLE students (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    class_id INT,
    -- 下面这句是重点:
    FOREIGN KEY (class_id) REFERENCES classes(id)
);

  * FOREIGN KEY (class_id):指定当前表哪一列是外键。
  * REFERENCES classes(id):指定它“引用”或者是“依赖”哪张表的哪一列。

例1:现在,请你作为首席数据库架构师,设计一张orders(订单表)
要求:
1.  id:整数,主键。
2.  user_id:整数。关键点:这一列必须是外键,关联到 users表的id列。(也就是说,必须是存在的用户才能下订单)
请尝试写出这个带有外键的 CREATE TABLE语句!
(提示:FOREIGN KEY (本表列名) REFERENCES 对方表名(对方列名))

CREATE TABLE orders (
    id INT PRIMARY KEY,
    user_id INT,       -- 第一步:先创建这一列!
    -- name VARCHAR(50), -- (这一列可要可不要)
    
    -- 第二步:再给这一列加锁
    FOREIGN KEY (user_id) REFERENCES users(id)
);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
总结
# 📜 MySQL SQL 极速速查表 (Cheat Sheet)

### 1\. 基础四件套 (CRUD)

最常用的增删改查。

| 操作 | 语法示例 | 说明 |
| :--- | :--- | :--- |
| **增 (Create)** | `INSERT INTO students (name, score) VALUES ('张三', 90);` | 记得列名和值要一一对应。 |
| **删 (Delete)** | `DELETE FROM students WHERE name = '李四';` | **警报:** 没写 WHERE 会删光全表! |
| **改 (Update)** | `UPDATE students SET score = 100 WHERE name = '张三';` | **警报:** 没写 WHERE 会改全表! |
| **查 (Read)** | `SELECT * FROM students;` | `*` 代表所有列。 |

### 2\. 筛选与排序 (Filtering & Sorting)

精准找到你想要的数据。

  * **精确查找**:`WHERE score = 100`
  * **多条件**:`WHERE score > 60 AND gender = '男'`
  * **范围查找**:`WHERE score BETWEEN 80 AND 90`
  * **列表查找**:`WHERE name IN ('张三', '李四')`
  * **模糊搜索**:`WHERE name LIKE '张%'` (姓张的,后面跟任意字符)
  * **排序**:`ORDER BY score DESC` (降序:大→小) / `ASC` (升序:小→大)
  * **限制数量**:`LIMIT 3` (只看前 3)

### 3\. 数据统计 (Aggregation)

做报表必备。

  * **计数**:`COUNT(*)` (数有多少行)
  * **平均值**:`AVG(score)`
  * **最大/小**:`MAX(score)` / `MIN(score)`
  * **去重**:`DISTINCT name` (去掉重复的名字)
  * **分组统计**:
   
    SELECT class, AVG(score) FROM students
    GROUP BY class           -- 按班级分组
    HAVING AVG(score) > 80;  -- 筛选分组后的结果 (不用 WHERE!)

4. 多表连接 (Joins)

把散落在不同表的数据拼起来。

  • 内连接 (INNER JOIN)“交集”。两边都有才显示。
    1
    2
    3
    
    SELECT s.name, c.teacher 
    FROM students s
    INNER JOIN classes c ON s.class_id = c.id;
    
  • 左连接 (LEFT JOIN)“左边为主”。不管右边有没有,左边全保留(右边找不到填 NULL)。
    1
    2
    3
    
    SELECT s.name, c.teacher 
    FROM students s
    LEFT JOIN classes c ON s.class_id = c.id;
    

5. 表结构管理 (DDL)

架构师技能包。

  • 建表 (Create)
    1
    2
    3
    4
    5
    
    CREATE TABLE users (
        id INT PRIMARY KEY AUTO_INCREMENT, -- 主键,自动增长
        name VARCHAR(50) NOT NULL,         -- 必填
        class_id INT
    );
    
  • 修改表 (Alter)
    • 加列ALTER TABLE users ADD age INT;
    • 改列ALTER TABLE users MODIFY name VARCHAR(100);
    • 删列ALTER TABLE users DROP COLUMN age;
  • 删表 (Drop)DROP TABLE users; (慎用!数据全没)

6. 进阶黑科技 (Advanced)

提升性能与逻辑。

  • 创建索引 (提速)CREATE INDEX idx_name ON users (name);
  • 子查询 (套娃)
    1
    2
    3
    
    -- 找出比平均分高的人
    SELECT * FROM students 
    WHERE score > (SELECT AVG(score) FROM students);
    
  • 外键 (安全锁): 在 CREATE TABLE 时使用: FOREIGN KEY (class_id) REFERENCES classes(id)
本文采用 CC BY-NC-SA 4.0 许可协议
使用 Hugo 构建
主题 StackJimmy 设计