【MySQL--06】基本查询 表的CRUD

文章目录

【MySQL–06】表的增删该查

表的CRUD正是我们常说的增删改查:CREATE(创建) RETRIEVE(读取) UPDATE(更新) DELETE(删除)

1.1Create

语法:

insert [into] 表名 [(column [, column] ...)] values (value_list) [, (value_list)] ...

value_list: value, [, value] ...

示例:

Create Table: CREATE TABLE `student` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `sn` int(11) NOT NULL,
  `name` varchar(20) NOT NULL,
  `qq` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `sn` (`sn`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

1.1.1 单行数据+全列插入

插入两条记录,value_list数量必须和定义表的列的数量及顺序一致。

注意:这里在插入的时候,也可以不用指定id(当然,那时候就需要明确插入数据到那些列了),那么mysql会使用默认的值进行自增。

mysql> insert into student values (1,1000,'孙悟空',1234);
Query OK, 1 row affected (0.03 sec)

mysql> insert into student values (2,1001,'唐三藏',1235);
Query OK, 1 row affected (0.02 sec)

--查看插入结果
mysql> select * from student;
+----+------+-----------+------+
| id | sn   | name      | qq   |
+----+------+-----------+------+
|  1 | 1000 | 孙悟空    | 1234 |
|  2 | 1001 | 唐三藏    | 1235 |
+----+------+-----------+------+
2 rows in set (0.00 sec)

1.1.2 多行数据+指定列插入

插入两条记录,values_list数量必须和指定列数量及顺序一致

mysql> insert into student (id,sn,name) values (3,10002,'猪八戒');
Query OK, 1 row affected (0.03 sec)

mysql> insert into student (id,sn,name) values (3,10002,'猪八戒',null);
ERROR 1136 (21S01): Column count doesn't match value count at row 1
--查看插入结果
mysql> select * from student;
+----+-------+-----------+------+
| id | sn    | name      | qq   |
+----+-------+-----------+------+
|  1 |  1000 | 孙悟空    | 1234 |
|  2 |  1001 | 唐三藏    | 1235 |
|  3 | 10002 | 猪八戒    | NULL |
+----+-------+-----------+------+
3 rows in set (0.00 sec)

1.1.3 插入否则更新

由于主键或者唯一键对应的值已经存在而导致插入失败

mysql> desc student;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| id    | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| sn    | int(11)          | NO   | UNI | NULL    |                |
| name  | varchar(20)      | NO   |     | NULL    |                |
| qq    | varchar(20)      | YES  |     | NULL    |                |
+-------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql> select * from student;
+----+-------+-----------+------+
| id | sn    | name      | qq   |
+----+-------+-----------+------+
|  1 |  1000 | 孙悟空    | 1234 |
|  2 |  1001 | 唐三藏    | 1235 |
|  3 | 10002 | 猪八戒    | NULL |
+----+-------+-----------+------+
3 rows in set (0.00 sec)

mysql> insert into student (id,sn,name) values (1,10003,'沙和尚');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY' -- 发生主键冲突

可以选择性的进行同步更新操作语法:

insert ...on duplicate key update column = values[,column = value] ...

on duplicate key:当发生重复key的时候

举例:

mysql> select * from student;
+----+-------+-----------+------+
| id | sn    | name      | qq   |
+----+-------+-----------+------+
|  1 |  1000 | 孙悟空    | 1234 |
|  2 |  1001 | 唐三藏    | 1235 |
|  3 | 10002 | 猪八戒    | NULL |
|  4 | 10003 | 沙和尚    | NULL |
+----+-------+-----------+------+
4 rows in set (0.00 sec)

--如果发生冲突就更新
mysql> insert into student (id,sn,name) values (1,10004,'太上老君') 
    -> on duplicate key update sn = 10004,name = '太上老君';
Query OK, 2 rows affected (0.04 sec)


mysql> select * from student;
+----+-------+--------------+------+
| id | sn    | name         | qq   |
+----+-------+--------------+------+
|  1 | 10004 | 太上老君     | 1234 |
|  2 |  1001 | 唐三藏       | 1235 |
|  3 | 10002 | 猪八戒       | NULL |
|  4 | 10003 | 沙和尚       | NULL |
+----+-------+--------------+------+
4 rows in set (0.00 sec)

三种情况:

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

通过MySQL函数获取收到影响的数据行数 select row_count();

mysql> insert into student values (null,12345,'白龙马',213412);
Query OK, 1 row affected (0.03 sec)

mysql> select row_count();
+-------------+
| row_count() |
+-------------+
|           1 |
+-------------+
1 row in set (0.00 sec)

1.1.4替换 REPLACE

  • 主键或者唯一键没有冲突,则直接插入
  • 主键或者唯一键有冲突,则删除后再插入

语法:在使用上和insert一样

replace into student values(null,10004,'曹操',32145);

mysql> select * from student;
+----+-------+-----------+--------+
| id | sn    | name      | qq     |
+----+-------+-----------+--------+
|  2 |  1001 | 唐三藏    | 1235   |
|  3 | 10002 | 猪八戒    | NULL   |
|  4 | 10003 | 沙和尚    | NULL   |
|  5 | 12345 | 白龙马    | 213412 |
|  6 | 10004 | 曹操      | 32145  |
+----+-------+-----------+--------+
5 rows in set (0.00 sec)

mysql> replace into student values(2,10005,'关羽',15234);
Query OK, 2 rows affected (0.03 sec)

mysql> select * from student;
+----+-------+-----------+--------+
| id | sn    | name      | qq     |
+----+-------+-----------+--------+
|  2 | 10005 | 关羽      | 15234  |
|  3 | 10002 | 猪八戒    | NULL   |
|  4 | 10003 | 沙和尚    | NULL   |
|  5 | 12345 | 白龙马    | 213412 |
|  6 | 10004 | 曹操      | 32145  |
+----+-------+-----------+--------+
5 rows in set (0.00 sec)

1.2 Retrieve

语法:

select 
	[distinct] {*|{column[,column] ...}
	[from 表名]
	[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 '英语成绩' 
); 
 
-- 插入测试数据 
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.00 sec) 
Records: 7 Duplicates: 0 Warnings: 0 

1.2.1select

1.2.1.1全列查找

通常情况下不建议使用*进行全列查询

原因:

  1. 查询的列越多,意味着需要传输的数据量越大。
  2. 可能会影响到索引的使用。
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)
1.2.1.2指令列查询

指定列的顺序不需要按照定义表的顺序来。

只是个自由,我想咋查就咋查

mysql> 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.01 sec)

mysql> select name,id,english from exam_result;
+-----------+----+---------+
| name      | id | english |
+-----------+----+---------+
| 唐三藏    |  1 |      56 |
| 孙悟空    |  2 |      77 |
| 猪悟能    |  3 |      90 |
| 曹孟德    |  4 |      67 |
| 刘玄德    |  5 |      45 |
| 孙权      |  6 |      78 |
| 宋公明    |  7 |      30 |
+-----------+----+---------+
7 rows in set (0.01 sec)
1.2.1.3查询字段为表达式

表达式不包含字段

查询给每个人的语文成绩+10之后的结果
mysql> select chinese from exam_result;
+---------+
| chinese |
+---------+
|      67 |
|      87 |
|      88 |
|      82 |
|      55 |
|      70 |
|      75 |
+---------+
7 rows in set (0.00 sec)

mysql> select chinese+10 from exam_result;
+------------+
| chinese+10 |
+------------+
|         77 |
|         97 |
|         98 |
|         92 |
|         65 |
|         80 |
|         85 |
+------------+
7 rows in set (0.00 sec)
查询每个人的总成绩
mysql> select id,name,chinese+math+english from exam_result;
+----+-----------+----------------------+
| id | name      | chinese+math+english |
+----+-----------+----------------------+
|  1 | 唐三藏    |                  221 |
|  2 | 孙悟空    |                  242 |
|  3 | 猪悟能    |                  276 |
|  4 | 曹孟德    |                  233 |
|  5 | 刘玄德    |                  185 |
|  6 | 孙权      |                  221 |
|  7 | 宋公明    |                  170 |
+----+-----------+----------------------+
7 rows in set (0.00 sec)

注:查询语句中的表达式并不会改变表的内容

1.2.1.4为查询结果指定别名

语法:

select column [AS] alias_name [...] from 表名;

查询每个人的总成绩并指定别名为总分
mysql> select id,name,chinese+math+english as 总分 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)

as可以省略

mysql> select id 编号,name 姓名,chinese+math+english 总分 from exam_result;
+--------+-----------+--------+
| 编号   | 姓名      | 总分   |
+--------+-----------+--------+
|      1 | 唐三藏    |    221 |
|      2 | 孙悟空    |    242 |
|      3 | 猪悟能    |    276 |
|      4 | 曹孟德    |    233 |
|      5 | 刘玄德    |    185 |
|      6 | 孙权      |    221 |
|      7 | 宋公明    |    170 |
+--------+-----------+--------+
7 rows in set (0.01 sec)
1.2.1.5结果去重
mysql> select Math From exam_result;
+------+
| Math |
+------+
|   98 |
|   78 |
|   98 |
|   84 |
|   85 |
|   73 |
|   65 |
+------+
7 rows in set (0.00 sec)

我们发现98重复了,那么我们要得到去重之后的结果只需要加上distinct即可

mysql> select distinct Math From exam_result;
+------+
| Math |
+------+
|   98 |
|   78 |
|   84 |
|   85 |
|   73 |
|   65 |
+------+
6 rows in set (0.00 sec)

1.2.2 where条件

条件查询:如果我们想在一定的条件下进行查询,我们就把这种有条件的查询就叫做条件查询。

在条件查询中,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)

案例:

1.2.2.1英语不及格的同学及英语成绩(<60)
mysql> select name,english from exam_result where english<60;
+-----------+---------+
| name      | english |
+-----------+---------+
| 唐三藏    |      56 |
| 刘玄德    |      45 |
| 宋公明    |      30 |
+-----------+---------+
3 rows in set (0.00 sec)
1.2.2.2语文成绩在[80,90]分的同学及语文成绩

使用AND进行条件连接

mysql> select name,chinese from exam_result where chinese >=80 and chinese <=90;

+-----------+---------+
| name      | chinese |
+-----------+---------+
| 孙悟空    |      87 |
| 猪悟能    |      88 |
| 曹孟德    |      82 |
+-----------+---------+
3 rows in set (0.00 sec)

使用between and 条件

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)
1.2.2.3数学成绩是58或者59或者98或者99分的同学及数学成绩

使用or进行条件连接

mysql> 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)

使用in条件

mysql> select name,math from exam_result where math in(58,59,98,99);
+-----------+------+
| name      | math |
+-----------+------+
| 唐三藏    |   98 |
| 猪悟能    |   98 |
+-----------+------+
2 rows in set (0.00 sec)
1.2.2.4姓孙的同学及孙某同学

%:匹配任意多个(包括0个)任意字符

mysql> select name from exam_result where name like '孙%';
+-----------+
| name      |
+-----------+
| 孙悟空    |
| 孙权      |
+-----------+
2 rows in set (0.00 sec)

_:匹配严格的一个任意字符

mysql> select name from exam_result where name like '孙_';
+--------+
| name   |
+--------+
| 孙权   |
+--------+
1 row in set (0.00 sec)
1.2.2.5语文成绩好于英语成绩的同学
mysql> 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)
1.2.2.6 总分在200分以下的同学

这里注意别名不能用在where条件中

mysql> select name,chinese+math+english 总分 from exam_result where chinese+english+math<200;
+-----------+--------+
| name      | 总分   |
+-----------+--------+
| 刘玄德    |    185 |
| 宋公明    |    170 |
+-----------+--------+
2 rows in set (0.00 sec)
1.2.2.7 语文成绩>80并且不性孙的同学

ANDNOT的使用

mysql> select name,chinese from exam_result where chinese>80 and name not like '孙%';
+-----------+---------+
| name      | chinese |
+-----------+---------+
| 猪悟能    |      88 |
| 曹孟德    |      82 |
+-----------+---------+
2 rows in set (0.00 sec)
1.2.2.8孙某同学,否则要求总成绩>200并且语文成绩<数学成绩并且英语成绩>80
mysql> select name,chinese,math,english from exam_result where name like '孙%' or(chinese+english+math >200 and chinese<math and english > 80);
+-----------+---------+------+---------+
| name      | chinese | math | english |
+-----------+---------+------+---------+
| 孙悟空    |      87 |   78 |      77 |
| 猪悟能    |      88 |   98 |      90 |
| 孙权      |      70 |   73 |      78 |
+-----------+---------+------+---------+
3 rows in set (0.00 sec)
1.2.2.9 NULL的查询
mysql> select * from student;
+----+-------+-----------+--------+
| id | sn    | name      | qq     |
+----+-------+-----------+--------+
|  2 | 10005 | 关羽      | 15234  |
|  3 | 10002 | 猪八戒    | NULL   |
|  4 | 10003 | 沙和尚    | NULL   |
|  5 | 12345 | 白龙马    | 213412 |
|  6 | 10004 | 曹操      | 32145  |
+----+-------+-----------+--------+
5 rows in set (0.00 sec)

查询qq号存在的同学姓名

mysql> select name,qq from student where qq is not null;
+-----------+--------+
| name      | qq     |
+-----------+--------+
| 关羽      | 15234  |
| 白龙马    | 213412 |
| 曹操      | 32145  |
+-----------+--------+
3 rows in set (0.00 sec)

NULL和NULL的比较

mysql> select NULL = NULL,NULL = 1 ,NULL = 0;
+--------------+---------+----------+
| NULL  = NULL | NULL =1 | NULL = 0 |
+--------------+---------+----------+
|         NULL |    NULL |     NULL |
+--------------+---------+----------+
1 row in set (0.00 sec)
mysql> select NULL<=>NULL,NULL<=>1 ,NULL<=>0;
+-------------+----------+----------+
| NULL<=>NULL | NULL<=>1 | NULL<=>0 |
+-------------+----------+----------+
|           1 |        0 |        0 |
+-------------+----------+----------+
1 row in set (0.00 sec)

1.2.3 结果排序

语法:

---ASC: 升序(从小到大)
---DESC:降序(从大到小)
默认为升序 ASC

SELECT ... FROM 表名 	[where] order by column [asc/desc],[....];

注意:没有 order by子句的查询,返回的顺序是未定义的,永远不要依赖这个顺序

案例:

1.2.3.1数学成绩升序排序显示
mysql> select name,math from exam_result order by math asc;
+-----------+------+
| name      | math |
+-----------+------+
| 宋公明    |   65 |
| 孙权      |   73 |
| 孙悟空    |   78 |
| 曹孟德    |   84 |
| 刘玄德    |   85 |
| 唐三藏    |   98 |
| 猪悟能    |   98 |
+-----------+------+
7 rows in set (0.00 sec)
1.2.3.2同学及QQ号,按QQ号升序排序显示
mysql> select name,qq from student order by qq asc;
+-----------+--------+
| name      | qq     |
+-----------+--------+
| 猪八戒    | NULL   |
| 沙和尚    | NULL   |
| 关羽      | 15234  |
| 白龙马    | 213412 |
| 曹操      | 32145  |
+-----------+--------+
5 rows in set (0.00 sec)

NULL视为比任何值都小,升序出现在最上面,降序出现在最下面。

1.2.3.3查询同学各门成绩,依次按照数学降序,英语升序,语文升序的方式显示
mysql> select name ,chinese,math,english from exam_result order by math desc,chinese asc , english asc;
+-----------+---------+------+---------+
| name      | chinese | math | english |
+-----------+---------+------+---------+
| 唐三藏    |      67 |   98 |      56 |
| 猪悟能    |      88 |   98 |      90 |
| 刘玄德    |      55 |   85 |      45 |
| 曹孟德    |      82 |   84 |      67 |
| 孙悟空    |      87 |   78 |      77 |
| 孙权      |      70 |   73 |      78 |
| 宋公明    |      75 |   65 |      30 |
+-----------+---------+------+---------+
7 rows in set (0.00 sec)
1.2.3.4查询同学及其总分,由高到低排序
mysql> select name,chinese+math+english 总分 from exam_result order by 总分 desc;
+-----------+--------+
| name      | 总分   |
+-----------+--------+
| 猪悟能    |    276 |
| 孙悟空    |    242 |
| 曹孟德    |    233 |
| 唐三藏    |    221 |
| 孙权      |    221 |
| 刘玄德    |    185 |
| 宋公明    |    170 |
+-----------+--------+
7 rows in set (0.00 sec)

order by子句中可以使用列别名

1.2.3.5 查询姓孙的同学或者姓曹的同学数学成绩,结果按照数学成绩由高到低显示
mysql> 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)

1.2.4 筛选分页结果

语法:limit子句

-- 起始下标为 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,避免因为表中的数据过大,查询全表数据导致数据库卡死,按id进行分页,每页3条记录,分别显示第1,2,3页

  • 第一页
mysql> select id ,name,math,english,chinese from exam_result order by id limit 3 offset 0;
+----+-----------+------+---------+---------+
| id | name      | math | english | chinese |
+----+-----------+------+---------+---------+
|  1 | 唐三藏    |   98 |      56 |      67 |
|  2 | 孙悟空    |   78 |      77 |      87 |
|  3 | 猪悟能    |   98 |      90 |      88 |
+----+-----------+------+---------+---------+
3 rows in set (0.00 sec)
  • 第二页
mysql> select id,name,math,english,chinese from exam_result order by id limit 3 offset 3;
+----+-----------+------+---------+---------+
| id | name      | math | english | chinese |
+----+-----------+------+---------+---------+
|  4 | 曹孟德    |   84 |      67 |      82 |
|  5 | 刘玄德    |   85 |      45 |      55 |
|  6 | 孙权      |   73 |      78 |      70 |
+----+-----------+------+---------+---------+
3 rows in set (0.00 sec)
  • 第三页 --如果结果不足3个,不会有影响
mysql> select id,name,math,english,chinese from exam_result order by id limit 3 offset 6;
+----+-----------+------+---------+---------+
| id | name      | math | english | chinese |
+----+-----------+------+---------+---------+
|  7 | 宋公明    |   65 |      30 |      75 |
+----+-----------+------+---------+---------+
1 row in set (0.00 sec)

1.3 Update

语法:

UPDATE 表名 set column =expr [,column = expr ...] [where...] [order by...][limit...]

作用:对查询到的结果进行列值更新

案例:

1.3.1将孙悟空的数学成绩变更为80分

--查看原数据
mysql> select name,math from exam_result where name = '孙悟空';
+-----------+------+
| name      | math |
+-----------+------+
| 孙悟空    |   78 |
+-----------+------+
1 row in set (0.00 sec)

--数据更新
mysql> update exam_result set math = 80 where name = '孙悟空';
Query OK, 1 row affected (0.03 sec)
Rows matched: 1  Changed: 1  Warnings: 0

--查看更新后数据
mysql> select name,math from exam_result where name = '孙悟空';
+-----------+------+
| name      | math |
+-----------+------+
| 孙悟空    |   80 |
+-----------+------+
1 row in set (0.00 sec)

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

查看原数据

mysql> select name,math,chinese+math+english 总分 from exam_result order by 总 分 asc limit 3;
+-----------+------+--------+
| name      | math | 总分   |
+-----------+------+--------+
| 宋公明    |   65 |    170 |
| 刘玄德    |   85 |    185 |
| 唐三藏    |   98 |    221 |
+-----------+------+--------+
3 rows in set (0.00 sec)

数据更新

mysql> update exam_result set math = math+30 order by math+chinese+english asc limit 3;
Query OK, 3 rows affected (0.02 sec)
Rows matched: 3  Changed: 3  Warnings: 0

查看更新后的数学成绩

原:
+-----------+------+--------+
| name      | math | 总分   |
+-----------+------+--------+
| 宋公明    |   65 |    170 |
| 刘玄德    |   85 |    185 |
| 唐三藏    |   98 |    221 |
+-----------+------+--------+

mysql> select name,math from exam_result order by math;
+-----------+------+    
| name      | math |
+-----------+------+
| 孙权      |   73 |
| 孙悟空    |   80 |
| 曹孟德    |   84 |
| 宋公明    |   95 | -- 65-->95
| 猪悟能    |   98 |
| 刘玄德    |  115 | -- 85-->115
| 唐三藏    |  128 | -- 98-->128
+-----------+------+
7 rows in set (0.00 sec)

1.3.4将所有同学的语文成绩更新为原来的2倍

查看原数据

mysql> select name,chinese from exam_result;
+-----------+---------+
| name      | chinese |
+-----------+---------+
| 唐三藏    |      67 |
| 孙悟空    |      87 |
| 猪悟能    |      88 |
| 曹孟德    |      82 |
| 刘玄德    |      55 |
| 孙权      |      70 |
| 宋公明    |      75 |
+-----------+---------+
7 rows in set (0.01 sec)

更新数据并查看新数据

mysql> update exam_result set chinese = chinese*2;
Query OK, 7 rows affected (0.03 sec)
Rows matched: 7  Changed: 7  Warnings: 0

mysql> select name,chinese from exam_result;
+-----------+---------+
| name      | chinese |
+-----------+---------+
| 唐三藏    |     134 |
| 孙悟空    |     174 |
| 猪悟能    |     176 |
| 曹孟德    |     164 |
| 刘玄德    |     110 |
| 孙权      |     140 |
| 宋公明    |     150 |
+-----------+---------+
7 rows in set (0.00 sec)

1.4 Delete

1.4.1删除数据

语法:

DELETE FROM 表名 [WHERE...] [ORDERBY...] [LIMIT...]

案例:

1.4.1.1删除孙悟空同学的成绩

查看原数据

mysql> select * from exam_result where name = '孙悟空';
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  2 | 孙悟空    |     174 |   80 |      77 |
+----+-----------+---------+------+---------+
1 row in set (0.00 sec)

删除数据并查看

mysql> delete from exam_result where name = '孙悟空';
Query OK, 1 row affected (0.04 sec)

mysql> select * from exam_result where name = '孙悟空';
Empty set (0.00 sec)
1.4.1.2 删除整张表数据

注意:删除整表操作要谨慎!

准备测试表

mysql> create table for_delete(
    -> id int primary key auto_increment,
    -> name char(20)
    -> );
Query OK, 0 rows affected (0.13 sec)

插入测试数据

mysql> insert into for_delete values (1,'蔡徐坤'),(2,'陈琳'),(3,'Lisa');
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0

查看测试数据

mysql> select * from for_delete;
+------+-----------+
| id   | name      |
+------+-----------+
|    1 | 蔡徐坤    |
|    2 | 陈琳      |
|    3 | Lisa      |
+------+-----------+
3 rows in set (0.00 sec)

删除整表数据

mysql> delete from for_delete;
Query OK, 3 rows affected (0.02 sec)

查看删除结果

mysql> select * from for_delete;
Empty set (0.00 sec)

再插入一条数据,让id自增

mysql> insert into for_delete values(null,'Jennie');
Query OK, 1 row affected (0.03 sec)

查看数据

mysql> select * from for_delete;
+----+--------+
| id | name   |
+----+--------+
|  4 | Jennie |
+----+--------+
1 row in set (0.00 sec)

查看表结构,会有AUTO_INCREMENT=n

mysql> show create table for_delete \G
*************************** 1. row ***************************
       Table: for_delete
Create Table: CREATE TABLE `for_delete` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` char(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

我们可以发现,删除表数据并不会将auto_increment=n的值置为1,后续的插入依然按照最后一次插入的值为基础往后自增

1.4.2 截断表 truncate

语法:

truncate [table] 表名;

注意:这个操作慎用

  1. 只能对整表操作,不能像delete一样针对部分数据操作
  2. 实际上MySQL不对数据操作,所以比delete更快,但是truncate在删除数据的时候,并不经过真正的事务,所以无法回滚
  3. 会重置auto_increment项目

准备测试表

mysql> create table for_truncate( id int primary key auto_increment, name varchar(20));
Query OK, 0 rows affected (0.24 sec)

插入测试数据

mysql> insert into for_truncate values (1,'Lisa'),(2,'Rose'),(3,'Jennie')
,(4,'Jisoo');
Query OK, 4 rows affected (0.04 sec)
Records: 4  Duplicates: 0  Warnings: 0

查看测试数据

mysql> select * from for_truncate;
+----+--------+
| id | name   |
+----+--------+
|  1 | Lisa   |
|  2 | Rose   |
|  3 | Jennie |
|  4 | Jisoo  |
+----+--------+
4 rows in set (0.01 sec)

截断整表数据,注意影响行数是0,所以实际上没有对数据真正操作

mysql> truncate for_truncate;
Query OK, 0 rows affected (0.13 sec)

查看删除结果

mysql> select * from for_truncate;
Empty set (0.01 sec)

再插入一条数据,自增id重新增长

mysql> insert into for_truncate values (null,'key');
Query OK, 1 row affected (0.02 sec)

mysql> select * from for_truncate;
+----+------+
| id | name |
+----+------+
|  1 | key  |
+----+------+
1 row in set (0.00 sec)

查看表结构,会有auto_increment = 2

mysql> show create table for_truncate \G
*************************** 1. row ***************************
       Table: for_truncate
Create Table: CREATE TABLE `for_truncate` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

1.5插入查询结果

语法:

insert into 表名 [(column [,column...])] select ...

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

创建原数据表

mysql> create table duplicate_table(
    -> id int,
    -> name varchar(20));
Query OK, 0 rows affected (0.25 sec)

插入测试数据

mysql> insert into duplicate_table values(100,'a'),(200,'b'),(300,'c'),(100,'a'),(200,'b'),(200,'b');
Query OK, 6 rows affected (0.05 sec)
Records: 6  Duplicates: 0  Warnings: 0

查看测试数据

mysql> select * from duplicate_table;
+------+------+
| id   | name |
+------+------+
|  100 | a    |
|  200 | b    |
|  300 | c    |
|  100 | a    |
|  200 | b    |
|  200 | b    |
+------+------+
6 rows in set (0.01 sec)

思路

  1. 创建一张空表no_duplicate_table,结构和duplicate_table一样
  2. duplicate_table的去重数据插入到no_duplicate_table
  3. 通过重命名表,实现原子的去重操作

创建一张空表no_duplicate_table,结构和duplicate_table一样

mysql> create table no_duplicate_table like duplicate_table;
Query OK, 0 rows affected (0.26 sec)

duplicate_table的去重数据插入到no_duplicate_table

mysql> insert into no_duplicate_table select distinct * from duplicate_table;
Query OK, 3 rows affected (0.04 sec)
Records: 3  Duplicates: 0  Warnings: 0

通过重命名表,实现原子的去重操作

mysql> rename table duplicate_table to old_duplicate_table;
Query OK, 0 rows affected (0.07 sec)

mysql> rename table no_duplicate_table to duplicate_table;
Query OK, 0 rows affected (0.07 sec)

查看最终结果

mysql> show tables;
+--------------------------+
| Tables_in_104_db_lesson6 |
+--------------------------+
| duplicate_table          |
| exam_result              |
| for_delete               |
| for_truncate             |
| old_duplicate_table      |
| student                  |
+--------------------------+
6 rows in set (0.00 sec)

mysql> select * from duplicate_table;
+------+------+
| id   | name |
+------+------+
|  100 | a    |
|  200 | b    |
|  300 | c    |
+------+------+
3 rows in set (0.00 sec)

1.6聚合函数

函数说明
count([distinct] expr)返回查询到的数据的数量
sum([distinct] expr)返回查询到的数据的总和,不是数字没有意义
avg([distinct] expr)返回查询到的数据的平均值,不是数字没有意义
max ([distinct] expr)返回查询到的数据的最大值,不是数字没有意义
min ([distinct] expr)返回查询到的数据的最小值,不是数字没有意义

案例:

1.6.1统计班级共有多少同学

  • 使用 * 做统计,不受NULL影响
mysql> select count(*) from exam_result;
+----------+
| count(*) |
+----------+
|        6 |
+----------+
1 row in set (0.00 sec)

--验证
mysql> select * from exam_result;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  1 | 唐三藏    |     134 |  128 |      56 |
|  3 | 猪悟能    |     176 |   98 |      90 |
|  4 | 曹孟德    |     164 |   84 |      67 |
|  5 | 刘玄德    |     110 |  115 |      45 |
|  6 | 孙权      |     140 |   73 |      78 |
|  7 | 宋公明    |     150 |   95 |      30 |
+----+-----------+---------+------+---------+
6 rows in set (0.00 sec)
  • 使用表达式统计
mysql> select count(1) from exam_result;
+----------+
| count(1) |
+----------+
|        6 |
+----------+
1 row in set (0.00 sec)

1.6.2统计班收集的qq号有多少

NULL不会计入结果

mysql> select count(qq) from student;
+-----------+
| count(qq) |
+-----------+
|         3 |
+-----------+
1 row in set (0.00 sec)

--验证
mysql> select * from student;
+----+-------+-----------+--------+
| id | sn    | name      | qq     |
+----+-------+-----------+--------+
|  2 | 10005 | 关羽      | 15234  |
|  3 | 10002 | 猪八戒    | NULL   |
|  4 | 10003 | 沙和尚    | NULL   |
|  5 | 12345 | 白龙马    | 213412 |
|  6 | 10004 | 曹操      | 32145  |
+----+-------+-----------+--------+
5 rows in set (0.00 sec)

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

  • count(math)统计是的全部成绩
mysql> select count(math) from exam_result;
+-------------+
| count(math) |
+-------------+
|           6 |
+-------------+
1 row in set (0.00 sec)
  • count(distinct math)统计的是去重成绩数量
mysql> select count(distinct math) from exam_result;
+----------------------+
| count(distinct math) |
+----------------------+
|                    5 |
+----------------------+
1 row in set (0.00 sec)

--验证
mysql> select math from exam_result;
+------+
| math |
+------+
|   98 |
|   98 |
|   84 |
|  115 |
|   73 |
|   95 |
+------+
6 rows in set (0.00 sec)

1.6.4统计数学成绩总分

mysql> select sum(math) from exam_result;
+-----------+
| sum(math) |
+-----------+
|       563 |
+-----------+
1 row in set (0.00 sec)

1.6.5统计平均总分

mysql> select avg(chinese+math+english) from exam_result;
+---------------------------+
| avg(chinese+math+english) |
+---------------------------+
|                     300.5 |
+---------------------------+
1 row in set (0.00 sec)

1.6.6查找英语的最高分和最低分

最高分

mysql> select max(english) from exam_result;
+--------------+
| max(english) |
+--------------+
|           90 |
+--------------+
1 row in set (0.00 sec)

最低分

mysql> select min(english) from exam_result;
+--------------+
| min(english) |
+--------------+
|           30 |
+--------------+
1 row in set (0.00 sec)

验证

mysql> select english from exam_result order by english desc;
+---------+
| english |
+---------+
|      90 |
|      78 |
|      67 |
|      56 |
|      45 |
|      30 |
+---------+
6 rows in set (0.00 sec)

1.7 group by子句的使用

select中使用group by子句可以对指定列进行分组查询

select column1,column2,...from 表名 group by column;

案例

  • 准备工作,创建一个雇员信息表(scott.sql链接)
    • EMP员工表
    • DEPT部门表
    • SALGRADE工资等级表
  • 显示每个部门的平均工资和最高工资
mysql> select deptno,avg(sal),max(sal) from emp group by deptno;
+--------+-------------+----------+
| deptno | avg(sal)    | max(sal) |
+--------+-------------+----------+
|     10 | 2916.666667 |  5000.00 |
|     20 | 2175.000000 |  3000.00 |
|     30 | 1566.666667 |  2850.00 |
+--------+-------------+----------+
3 rows in set (0.00 sec)
  • 显示每个部门的每种岗位的平均工资和最低工资
mysql> select avg(sal),min(sal),job,deptno from emp group by deptno,job;
+-------------+----------+-----------+--------+
| avg(sal)    | min(sal) | job       | deptno |
+-------------+----------+-----------+--------+
| 1300.000000 |  1300.00 | CLERK     |     10 |
| 2450.000000 |  2450.00 | MANAGER   |     10 |
| 5000.000000 |  5000.00 | PRESIDENT |     10 |
| 3000.000000 |  3000.00 | ANALYST   |     20 |
|  950.000000 |   800.00 | CLERK     |     20 |
| 2975.000000 |  2975.00 | MANAGER   |     20 |
|  950.000000 |   950.00 | CLERK     |     30 |
| 2850.000000 |  2850.00 | MANAGER   |     30 |
| 1400.000000 |  1250.00 | SALESMAN  |     30 |
+-------------+----------+-----------+--------+
9 rows in set (0.00 sec)
  • 显示平均工资低于2000的部门和它的平均工资

    • 统计各个部门的平均工资
    mysql> select avg(sal) from emp group by deptno;
    +-------------+
    | avg(sal)    |
    +-------------+
    | 2916.666667 |
    | 2175.000000 |
    | 1566.666667 |
    +-------------+
    3 rows in set (0.00 sec)
    
    • having 和 group by 配合使用,对group by结果进行过滤
    mysql> select avg(sal) as my_avg from emp group by deptno having my_avg<2000;
    +-------------+
    | my_avg      |
    +-------------+
    | 1566.666667 |
    +-------------+
    1 row in set (0.00 sec)
    

having经常和gruop by配合使用,作用是对分组进行筛选,作用有点像where

总结:SQL查询中各个关键字的执行先后顺序

from > on > join > where > group by > with > having > select > distinct > order by >limit

(本篇完)

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白又菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值