目录
1. Create
2. Retrieve
2.1. SELECT列
2.1.1. 全列查询
2.1.2. 指定列查询
2.1.3. 查询字段为表达式
2.1.4. 为查询结果指定别名
2.1.5. 结果去重
2.2. WHERE条件
2.2.1. 年龄小于19的同学
2.2.2. id在2~3的同学
2.2.3. id为1和4的同学
2.2.4. 姓张的同学及张某的同学
2.3. 结果排序
2.3.1. 年龄按照升序
2.3.2. 年龄按照降序
2.3.3. 查询同学信息,依次按照年龄降序,id升序的方式显示
2.4. 筛选分页结果
2.4.1. 按 id 进行分页
3. Update
3.1. 将id为1的同学name改为麻子
3.2. 将所有同学的年龄+2
4. Delete
4.1. 删除麻子同学的信息
4.2. 删除整张表
4.3. 截断表
4.4. 插入查询结果
5. 聚合函数
5.1. 统计班级共有多少同学
5.2. 统计年龄的总和
5.3. 统计平均年龄
5.4. 返回年龄最大值和最小值
6. GROUP BY子句的使用
6.1. 显示每个订单编号中的最高销售数量
6.2. 显示销售数量低于5的订单信息
表的增删查改也叫做CRUD:CREATE 创建,RETRIEVE读取,UPDATE更新,DELETE函数。
1. Create
创建一张学生表:
CREATE TABLE students (
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
sn INT NOT NULL UNIQUE,
name VARCHAR(20) NOT NULL,
qq VARCHAR(20)
);
单行数据 + 全列插入。
全列插入的时候,必须按照创建表的顺序来插入数据.
INSERT INTO students VALUES(1,101,'a',NULL);
多行数据 + 指定列插入
指定列插入可以在表明后面跟上要插入的列.
INSERT INTO students(id, sn, name) VALUES(2,102, 'b'),(3, 103,'c');
插入否则更新
由于主键或者唯一键对应的值已经存在而导致插入失败
INSERT INTO students VALUES(1,104,'d',NULL);
INSERT INTO students VALUES(4,101,'d',NULL);
对于这种情况,可以选择性的进行同步更新操作语法:
INSERT ... ON DUPLICATE KEY UPDATE
column = value [, column = value] ...
INSERT INTO students VALUES (3,103,'d','123456') ON DUPLICATE
KEY UPDATE sn = 103, name = 'd';
这条数据已经存在过了,会产生冲突,在添加了同步更新之后,新数据会把旧数据给覆盖。
-- 0 row affected: | 表中有冲突数据,但冲突数据的值和 update 的值相等 |
替换
-- 主键 或者 唯一键 没有冲突,则直接插入;
-- 主键 或者 唯一键 如果冲突,则删除后再插入;
REPLACE INTO students (sn, name) VALUES(102, '13462');
-- 1 row affected: | 表中没有冲突数据,数据被插入 |
2. Retrieve
语法:
SELECT
[DISTINCT] {* | {column [, column] ...}
[FROM table_name]
[WHERE ...]
[ORDER BY column [ASC | DESC], ...]
LIMIT ...
在进行查询的时候,是不建议使用*号来进行全查询的。
案例:
创建表结构
CREATE TABLE students (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
age INT NOT NULL,
class VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
);
插入测试数据
INSERT INTO students (name, age, class) VALUES ('张三', 18, '一年级');
INSERT INTO students (name, age, class) VALUES ('李四', 19, '二年级');
INSERT INTO students (name, age, class) VALUES ('王五', 20, '三年级');
2.1. SELECT列
2.1.1. 全列查询
通常情况下不建议使用*进行全列查询,查询的列越多,意味着需要传输的数据量越大,并且可能会影响到索引的使用。---- 不建议规不建议,在日常学习的时候还是可以用的。
SELECT * FROM students;
2.1.2. 指定列查询
指定列查询的顺序不需要按照创建表的时候设定字段的顺序查询。
SELECT name FROM students;
2.1.3. 查询字段为表达式
表达式不包含字段
SELECT id, name, 10 FROM students;
表达式包含字段
SELECT id, name, age + 10 FROM students;
表达式包含多个字段
SELECT id, name, age + 10 + class FROM students;
2.1.4. 为查询结果指定别名
语法:
SELECT column [AS] alias_name [...] FROM table_name;
SELECT id, name, age + 10 AS 年龄加10 FROM students;
2.1.5. 结果去重
SELECT age FROM students;
SELECT DISTINCT age FROM students;
2.2. WHERE条件
比较运算符:
运算符 | 说明 |
>, >=, <, <= | 大于,大于等于,小于,小于等于 |
= | 等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL |
<=> | 等于,NULL 安全,例如 NULL <=> NULL 的结果是 TRUE(1) |
!=, <> | 不等于 |
BETWEEN a0 AND a1 | 范围匹配,[a0, a1],如果 a0 <= value <= a1,返回 TRUE(1) |
IN (option, ...) | 如果是 option 中的任意一个,返回 TRUE(1) |
IS NULL | 是 NULL |
IS NOT NULL | 不是 NULL |
LIKE | 模糊匹配。% 表示任意多个(包括 0 个)任意字符;_ 表示任意一个字符 |
逻辑运算符:
运算符 | 说明 |
AND | 多个条件必须都为 TRUE(1),结果才是 TRUE(1) |
OR | 任意一个条件为 TRUE(1), 结果为 TRUE(1) |
NOT | 条件为 TRUE(1),结果为 FALSE(0) |
2.2.1. 年龄小于19的同学
SELECT name ,age FROM students WHERE age <= 19;
2.2.2. id在2~3的同学
使用AND进行连接
SELECT id, name FROM students WHERE id >= 2 AND id <= 3;
'
使用BETWEEN……AND……条件
SELECT id, name FROM students WHERE id BETWEEN 2 AND 3;
2.2.3. id为1和4的同学
SELECT id, name FROM students WHERE id IN (1, 4);
SELECT id, name FROM students WHERE id = 1 OR id = 4;
2.2.4. 姓张的同学及张某的同学
INSERT INTO students (name, age, class) VALUES ('张三丰', 20, '三年级');
匹配任意多个(包括0个)任意字符
SELECT name FROM students WHERE name LIKE '张%';
严格匹配一个字符
SELECT name FROM students WHERE name LIKE '张_';
2.3. 结果排序
-- ASC 为升序(从小到大)
-- DESC 为降序(从大到小)
-- 默认为 ASC
SELECT ... FROM table_name [WHERE ...]
ORDER BY column [ASC|DESC], [...];
注意:没有 ORDER BY 子句的查询,返回的顺序是未定义的,永远不要依赖这个顺序
2.3.1. 年龄按照升序
SELECT name, age FROM students ORDER BY age;
SELECT name, age FROM students ORDER BY age ASC;
2.3.2. 年龄按照降序
SELECT name, age FROM students ORDER BY age DESC;
2.3.3. 查询同学信息,依次按照年龄降序,id升序的方式显示
SELECT id, name, age FROM students ORDER BY age DESC , id ASC ;
2.4. 筛选分页结果
语法:
-- 起始下标为 0
-- 从 0 开始,筛选 n 条结果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n;
-- 从 s 开始,筛选 n 条结果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT s, n;
-- 从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n OFFSET s;
建议:对未知表进行查询时,最好加一条 LIMIT 1,避免因为表中数据过大,查询全表数据导致数据库卡死
2.4.1. 按 id 进行分页
SELECT id, name, age FROM students ORDER BY id LIMIT 3 OFFSET 0;
3. Update
语法:
UPDATE table_name SET column = expr [, column = expr ...]
[WHERE ...] [ORDER BY ...] [LIMIT ...]
对查询到的结果进行列值更新
3.1. 将id为1的同学name改为麻子
UPDATE students SET name = '麻子' WHERE id = 1;
3.2. 将所有同学的年龄+2
没有WHERE子句,则更新全表
UPDATE students SET age = age + 2;
4. Delete
语法:
DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...]
4.1. 删除麻子同学的信息
DELETE FROM students WHERE name = '麻子';
4.2. 删除整张表
DELETE FROM TABLE_NAME
使用这个命令可以把表中的所有内容都给删除。
再插入新的数据
INSERT INTO students (name, age, class) VALUES ('赵六', 21, '四年级');
INSERT INTO students (name, age, class) VALUES ('孙七', 22, '五年级');
INSERT INTO students (name, age, class) VALUES ('周八', 23, '六年级');
INSERT INTO students (name, age, class) VALUES ('吴九', 24, '七年级');
INSERT INTO students (name, age, class) VALUES ('郑十', 25, '八年级');
插入数据之后发现,自增id是在原值上增长的。
查看表结构,发现存在一个AUTO_INCREMENT = 11。
SHOW CREATE TABLE students;
4.3. 截断表
语法:
TRUNCATE [TABLE] table_name
注意:这个操作慎用
- 只能对整表操作,不能像 DELETE 一样针对部分数据操作;
- 实际上 MySQL 不对数据操作,所以比 DELETE 更快,但是TRUNCATE在删除数据的时候,并不经过真正的事物,所以无法回滚
- 会重置 AUTO_INCREMENT 项
TRUNCATE students;
阶段之后查询,发现是一张空表,在插入数据。
INSERT INTO students (name, age, class) VALUES ('赵六', 21, '四年级');
INSERT INTO students (name, age, class) VALUES ('孙七', 22, '五年级');
INSERT INTO students (name, age, class) VALUES ('周八', 23, '六年级');
INSERT INTO students (name, age, class) VALUES ('吴九', 24, '七年级');
INSERT INTO students (name, age, class) VALUES ('郑十', 25, '八年级');
查询数据后发现,id不在是在原值的基础上增长的。
4.4. 插入查询结果
语法:
INSERT INTO table_name [(column [, column ...])] SELECT ...
在创建一张空表,结构和students一样。
CREATE TABLE cp_students LIKE students;
将students的数据插入到cp_students表中。
INSERT INTO cp_students SELECT DISTINCT * FROM students;
通过重命名表,实现去重操作
RENAME TABLE cp_students TO students;
5. 聚合函数
函数 | 说明 |
COUNT([DISTINCT] expr) | 返回查询到的数据的 数量 |
SUM([DISTINCT] expr) | 返回查询到的数据的 总和,不是数字没有意义 |
AVG([DISTINCT] expr) | 返回查询到的数据的 平均值,不是数字没有意义 |
MAX([DISTINCT] expr) | 返回查询到的数据的 最大值,不是数字没有意义 |
MIN([DISTINCT] expr) | 返回查询到的数据的 最小值,不是数字没有意义 |
5.1. 统计班级共有多少同学
SELECT COUNT(*) FROM students;
5.2. 统计年龄的总和
SELECT SUM(age) FROM students;
5.3. 统计平均年龄
SELECT AVG(age) FROM students;
5.4. 返回年龄最大值和最小值
SELECT MAX(age) FROM students;
SELECT MIN(age) FROM students;
6. GROUP BY子句的使用
在SELECT中使用GROUP BY子句可以对指定列进行分组查询。
select column1, column2, .. from table group by column;
案例:
CREATE TABLE sales (
order_id SERIAL PRIMARY KEY,
customer_id INT,
product_id INT,
quantity INT,
unit_price DECIMAL(10, 2),
total_price DECIMAL(10, 2),
order_date DATE
);
订单编号、客户编号、产品编号、销售数量、单价、总价和订单日期。
INSERT INTO sales (customer_id, product_id, quantity, unit_price, total_price, order_date)
VALUES
(101, 201, 5, 10.00, 50.00, '2024-03-01'),
(102, 202, 3, 15.00, 45.00, '2024-03-02'),
(103, 203, 2, 20.00, 40.00, '2024-03-03'),
(104, 201, 4, 10.00, 40.00, '2024-03-04'),
(105, 204, 6, 8.00, 48.00, '2024-03-05'),
(101, 202, 2, 15.00, 30.00, '2024-03-06'),
(102, 203, 1, 20.00, 20.00, '2024-03-07'),
(103, 201, 3, 10.00, 30.00, '2024-03-08'),
(104, 204, 5, 8.00, 40.00, '2024-03-09'),
(105, 202, 4, 15.00, 60.00, '2024-03-10');
6.1. 显示每个订单编号中的最高销售数量
SELECT order_id, MAX(quantity) AS max_quantity
FROM sales
GROUP BY order_id;
6.2. 显示销售数量低于5的订单信息
SELECT * FROM sales GROUP BY order_id
HAVING SUM(quantity) < 5;
--having经常和group by搭配使用,作用是对分组进行筛选,作用有些像where