> 文章列表 > [数据库]表的增删改查进阶

[数据库]表的增删改查进阶

[数据库]表的增删改查进阶

●🧑个人主页:你帅你先说.
●📃欢迎点赞👍关注💡收藏💖
●📖既选择了远方,便只顾风雨兼程。
●🤟欢迎大家有问题随时私信我!
●🧐版权:本文由[你帅你先说.]原创,CSDN首发,侵权必究。

📌📌📌为您导航📌📌📌

  • 1. 表的增删查改
    • 6.1 Create
    • 6.2 Retrieve
    • 6.3 Update
    • 6.4 Delete
  • 2.插入查询结果
  • 3.聚合函数
  • 4.group by子句的使用

1. 表的增删查改

CRUD : Create(创建), Retrieve(读取),Update(更新),Delete(删除)

6.1 Create

语法:

INSERT [INTO] table_name [(column [, column] ...)] VALUES (value_list) [, (value_list)] ... 
value_list: value, [, value] ...
mysql> create table students ( id int unsigned primary key auto_increment, sn int not null unique comment '学号', name varchar(20) not null, qq varchar(20) 
);
Query OK, 0 rows affected (0.03 sec)//单行数据插入
mysql> insert into students values (100, 10000, '张三', NULL);
Query OK, 1 row affected (0.01 sec)mysql> insert into students values (101, 10001, '李四', '10000');
Query OK, 1 row affected (0.00 sec)//多行数据插入
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: 0//插入并更新数据
insert into students (id, sn, name) values (100, 10000, '法外狂徒') on duplicate key update sn = 10000, name = '法外狂徒';
-- 0 row affected: 表中有冲突数据,但冲突数据的值和 update 的值相等 
-- 1 row affected: 表中没有冲突数据,数据被插入 
-- 2 row affected: 表中有冲突数据,并且数据已经被更新//替换数据
mysql> replace into students (sn, name) values (10001, '田七');
Query OK, 2 rows affected (0.01 sec)

duplicate会优先判定哪个是第一个冲突的数据,而replace会找出所有的冲突,替换成一个。

6.2 Retrieve

语法:

SELECT[DISTINCT] {* | {column [, column] ...} [FROM table_name] [WHERE ...] [ORDER BY column [ASC | DESC], ...] LIMIT ...
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 '英语成绩' 
);
Query OK, 0 rows affected (0.03 sec)//插入数据集
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);
Query OK, 7 rows affected (0.01 sec)
Records: 7  Duplicates: 0  Warnings: 0//全列查询
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.00 sec)//指定列查询
SELECT id, name, english 
FROM exam_result;
+----+-----------+---------+
| id | name      | english |
+----+-----------+---------+
|  1 | 唐三藏    |      56 |
|  2 | 孙悟空    |      77 |
|  3 | 猪悟能    |      90 |
|  4 | 曹孟德    |      67 |
|  5 | 刘玄德    |      45 |
|  6 | 孙权      |      78 |
|  7 | 宋公明    |      30 |
+----+-----------+---------+
7 rows in set (0.00 sec)//查询字段为表达式
SELECT id, name, english + 10 
FROM exam_result;
+----+-----------+--------------+
| id | name      | english + 10 |
+----+-----------+--------------+
|  1 | 唐三藏    |           66 |
|  2 | 孙悟空    |           87 |
|  3 | 猪悟能    |          100 |
|  4 | 曹孟德    |           77 |
|  5 | 刘玄德    |           55 |
|  6 | 孙权      |           88 |
|  7 | 宋公明    |           40 |
+----+-----------+--------------+
7 rows in set (0.00 sec)//为查询结果指定别名
SELECT id, name, chinese + math + english 总分 
FROM exam_result;
+----+-----------+--------+
| id | name      | 总分   |
+----+-----------+--------+
|  1 | 唐三藏    |    221 |
|  2 | 孙悟空    |    242 |
|  3 | 猪悟能    |    276 |
|  4 | 曹孟德    |    233 |
|  5 | 刘玄德    |    185 |
|  6 | 孙权      |    221 |
|  7 | 宋公明    |    170 |
+----+-----------+--------+
7 rows in set (0.00 sec)//结果去重
SELECT DISTINCT math FROM exam_result;
+------+
| math |
+------+
|   98 |
|   78 |
|   84 |
|   85 |
|   73 |
|   65 |
+------+
6 rows in set (0.00 sec)//where条件查询
//查询英语不及格的同学并显示英语成绩
SELECT name, english FROM exam_result WHERE english < 60;
+-----------+---------+
| name      | english |
+-----------+---------+
| 唐三藏    |      56 |
| 刘玄德    |      45 |
| 宋公明    |      30 |
+-----------+---------+
3 rows in set (0.00 sec)//查询语文成绩在 [80, 90] 分的同学并显示语文成绩
SELECT name, chinese 
FROM exam_result 
WHERE chinese >= 80 AND chinese <= 90;
+-----------+---------+
| name      | chinese |
+-----------+---------+
| 孙悟空    |      87 |
| 猪悟能    |      88 |
| 曹孟德    |      82 |
+-----------+---------+
3 rows in set (0.00 sec)//查询数学成绩是 58 或者 59 或者 98 或者 99 分的同学并显示数学成绩
SELECT name, math 
FROM exam_result 
WHERE math = 58 OR math = 59 OR math = 98 OR math = 99;
+-----------+------+
| name      | math |
+-----------+------+
| 唐三藏    |   98 |
| 猪悟能    |   98 |
+-----------+------+
2 rows in set (0.00 sec)
//也可以写成
SELECT name, math 
FROM exam_result 
WHERE math IN (58, 59, 98, 99);
+-----------+------+
| name      | math |
+-----------+------+
| 唐三藏    |   98 |
| 猪悟能    |   98 |
+-----------+------+
2 rows in set (0.00 sec)//查询姓孙的同学及孙某同学
//查询姓孙的同学
mysql> SELECT name FROM exam_result WHERE name LIKE '孙%';
+-----------+
| name      |
+-----------+
| 孙悟空    |
| 孙权      |
+-----------+
2 rows in set (0.00 sec)//查询孙某同学
SELECT name FROM exam_result WHERE name LIKE '孙_';
+--------+
| name   |
+--------+
| 孙权   |
+--------+
1 row in set (0.00 sec)//语文成绩高于英语成绩的同学
SELECT name, chinese, english 
FROM exam_result 
WHERE chinese > english;
+-----------+---------+---------+
| name      | chinese | english |
+-----------+---------+---------+
| 唐三藏    |      67 |      56 |
| 孙悟空    |      87 |      77 |
| 曹孟德    |      82 |      67 |
| 刘玄德    |      55 |      45 |
| 宋公明    |      75 |      30 |
+-----------+---------+---------+
5 rows in set (0.00 sec)//总分在 200 分以下的同学
SELECT name, chinese + math + english 总分 
FROM exam_result 
WHERE chinese + math + english < 200;
+-----------+--------+
| name      | 总分   |
+-----------+--------+
| 刘玄德    |    185 |
| 宋公明    |    170 |
+-----------+--------+
2 rows in set (0.00 sec)
//注意,这里不能写成总分<200,因为这条SQL语句在执行时where的优先级更高//想要使用别名可以使用HAVING语句
SELECT name, chinese + math + english 总分 FROM exam_result HAVING 总分 < 200;
+-----------+--------+
| name      | 总分   |
+-----------+--------+
| 刘玄德    |    185 |
| 宋公明    |    170 |
+-----------+--------+
2 rows in set (0.00 sec)//语文成绩 > 80 并且不姓孙的同学
SELECT name, chinese FROM exam_result WHERE chinese > 80 AND name NOT LIKE '孙%';
+-----------+---------+
| name      | chinese |
+-----------+---------+
| 猪悟能    |      88 |
| 曹孟德    |      82 |
+-----------+---------+
2 rows in set (0.00 sec)//孙某同学,否则要求总成绩>200并且语文成绩<数学成绩并且英语成绩>80
SELECT name,chinese,math,english, chinese+math+english 总分 
FROM exam_result 
WHERE name LIKE '孙_' OR (chinese+math+english>200 ANDchinese<math AND english>80 
);
+-----------+---------+------+---------+--------+
| name      | chinese | math | english | 总分   |
+-----------+---------+------+---------+--------+
| 猪悟能    |      88 |   98 |      90 |    276 |
| 孙权      |      70 |   73 |      78 |    221 |
+-----------+---------+------+---------+--------+
2 rows in set (0.00 sec)//NULL的查询
SELECT name, qq 
FROM students 
WHERE qq IS NOT NULL;
Empty set (0.00 sec)
//NULL的比较不能使用=,而要使用<=>//结果排序
-- ASC 为升序(从小到大) 
-- DESC 为降序(从大到小) 
-- 默认为 ASC
//同学及数学成绩,按数学成绩升序显示
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)
// 同学及 qq 号,按 qq 号排序显示
SELECT name, qq 
FROM students 
ORDER BY qq;
+--------------+------+
| name         | qq   |
+--------------+------+
| 法外狂徒     | NULL |
| 李华         | NULL |
| 李明         | NULL |
| 李三一       | NULL |
+--------------+------+
4 rows in set (0.00 sec)//查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示
SELECT name, math, english, chinese 
FROM exam_result 
ORDER BY math DESC, english, chinese;
+-----------+------+---------+---------+
| name      | math | english | chinese |
+-----------+------+---------+---------+
| 唐三藏    |   98 |      56 |      67 |
| 猪悟能    |   98 |      90 |      88 |
| 刘玄德    |   85 |      45 |      55 |
| 曹孟德    |   84 |      67 |      82 |
| 孙悟空    |   78 |      77 |      87 |
| 孙权      |   73 |      78 |      70 |
| 宋公明    |   65 |      30 |      75 |
+-----------+------+---------+---------+
7 rows in set (0.00 sec)// 查询同学及总分,由高到低
-- ORDER BY 子句中可以使用列别名
SELECT name, chinese + english + math 总分
FROM exam_result 
ORDER BY 总分 DESC;
+-----------+--------+
| name      | 总分   |
+-----------+--------+
| 猪悟能    |    276 |
| 孙悟空    |    242 |
| 曹孟德    |    233 |
| 唐三藏    |    221 |
| 孙权      |    221 |
| 刘玄德    |    185 |
| 宋公明    |    170 |
+-----------+--------+
7 rows in set (0.00 sec)// 查询姓孙的同学或者姓曹的同学数学成绩,结果按数学成绩由高到低显示
SELECT name, math 
FROM exam_result 
WHERE name LIKE '孙%' OR name LIKE '曹%' 
ORDER BY math DESC;
+-----------+------+
| name      | math |
+-----------+------+
| 曹孟德    |   84 |
| 孙悟空    |   78 |
| 孙权      |   73 |
+-----------+------+
3 rows in set (0.00 sec)//筛选分页结果
SELECT id, name, math, english, chinese 
FROM exam_result 
ORDER BY id LIMIT 3 OFFSET 0;//意思是从id为OFFSET+1开始显示3个数据
+----+-----------+------+---------+---------+
| id | name      | math | english | chinese |
+----+-----------+------+---------+---------+
|  1 | 唐三藏    |   98 |      56 |      67 |
|  2 | 孙悟空    |   78 |      77 |      87 |
|  3 | 猪悟能    |   98 |      90 |      88 |
+----+-----------+------+---------+---------+
3 rows in set (0.00 sec)

6.3 Update

语法:

UPDATE table_name SET column = expr [, column = expr ...] [WHERE ...] [ORDER BY ...] [LIMIT ...]
//将孙悟空同学的数学成绩变更为 80 分
UPDATE exam_result 
SET math = 80 
WHERE name = '孙悟空';//将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分
UPDATE exam_result 
SET math = 60, chinese = 70 
WHERE name = '曹孟德';//将总成绩倒数前三的 3 位同学的数学成绩加上 30 分
UPDATE exam_result 
SET math = math + 30 
ORDER BY chinese + math + english LIMIT 3;//将所有同学的语文成绩更新为原来的 2 倍
UPDATE exam_result 
SET chinese = chinese * 2;

6.4 Delete

语法:

DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...]
//删除孙悟空同学的考试成绩
DELETE FROM exam_result WHERE name = '孙悟空';//删除整张表数据
DELETE FROM for_delete;//截断表
--1. 只能对整表操作,不能像 DELETE 一样针对部分数据操作。
--2. 实际上 MySQL 不对数据操作,所以比 DELETE 更快,但是TRUNCATE在删除数据的时候,并不经过真正的事物,所以无法回滚。
--3. 会重置AUTO_INCREMENT项,标号会重新从1开始,而若用delete删除,则会延续旧表的AUTO_INCREMENT。
TRUNCATE for_truncate;

2.插入查询结果

语法:

INSERT INTO table_name [(column [, column ...])] SELECT ...
//删除表中的的重复复记录,重复的数据只能有一份
-- 创建原数据表
CREATE TABLE duplicate_table (id int, name varchar(20));
Query OK, 0 rows affected (0.01 sec)
-- 插入测试数据
INSERT INTO duplicate_table VALUES (100, 'aaa'), (100, 'aaa'), (200, 'bbb'), (200, 'bbb'), (200, 'bbb'), (300, 'ccc'); 
Query OK, 6 rows affected (0.00 sec) 
Records: 6 Duplicates: 0 Warnings: 0-- 创建一张空表 no_duplicate_table,结构和 duplicate_table 一样
CREATE TABLE no_duplicate_table LIKE duplicate_table; 
Query OK, 0 rows affected (0.00 sec)-- 将 duplicate_table 的去重数据插入到 no_duplicate_table 
INSERT INTO no_duplicate_table 
SELECT DISTINCT * FROM duplicate_table; 
Query OK, 3 rows affected (0.00 sec) 
Records: 3 Duplicates: 0 Warnings: 0-- 通过重命名表,实现原子的去重操作
RENAME TABLE duplicate_table TO old_duplicate_table, no_duplicate_table TO duplicate_table;
Query OK, 0 rows affected (0.00 sec)-- 查看最终结果
SELECT * FROM duplicate_table;
+-----+------+ 
| id  | name | 
+-----+------+ 
| 100 | aaa  | 
| 200 | bbb  | 
| 300 | ccc  |
+------+-----+
3 rows in set (0.00 sec)

3.聚合函数

//统计班级共有多少同学
-- 使用 * 做统计,不受 NULL 影响
SELECT COUNT(*) FROM students;// 统计班级收集的 qq 号有多少
-- NULL 不会计入结果
SELECT COUNT(qq) FROM students;//统计本次考试的数学成绩分数个数
SELECT COUNT(math) FROM exam_result;
-- COUNT(DISTINCT math) 统计的是去重成绩数量
SELECT COUNT(DISTINCT math) FROM exam_result;//统计数学成绩总分
SELECT SUM(math) FROM exam_result;//统计平均总分
SELECT AVG(chinese + math + english) 平均总分 FROM exam_result;//返回英语最高分
SELECT MAX(english) FROM exam_result;//返回 > 70 分以上的数学最低分
SELECT MIN(math) FROM exam_result WHERE math > 70;

4.group by子句的使用

--准备工作,创建一个雇员信息表(来自oracle 9i的经典测试表)
--EMP员工表
--DEPT部门表
--SALGRADE工资等级表
--deptno部门号 sal工资 //如何显示每个部门的平均工资和最高工资
select deptno,avg(sal),max(sal) 
from EMP 
group by deptno;//显示每个部门的每种岗位的平均工资和最低工资
select avg(sal),min(sal),job, deptno 
from EMP 
group by deptno, job;//显示平均工资低于2000的部门和它的平均工资
select avg(sal) as myavg 
from EMP 
group by deptno having myavg<2000;

having经常和group by搭配使用,作用是对分组进行筛选,作用有些像where,但与where不同的是执行顺序,where的执行优先级总是靠前的,所以where里不能使用别名,而having是在满足条件的数据挑选完之后在按条件来进行分组,所以having可以使用别名。(where过滤表数据,having过滤分组后的数据)
SQL查询中各个关键字的执行先后顺序:from > on> join > where > group by > with > having > select> distinct > order by > limit。

喜欢这篇文章的可以给个一键三连点赞👍关注💡收藏💖

土地资源文秘网