0


MySQL基本查询

文章目录

表的增删查改

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

Create(创建)

基本语法:

INSERT[INTO] table_name
    [(column[,column]...)]VALUES(value_list)[,(value_list)]...

value_list: value,[,value]...

案例:

mysql>createtable students (-> id intunsignedprimarykeyauto_increment,-> sn intnotnulluniquecomment'学号',-> name varchar(20)notnull,-> email varchar(20)->)engine=innodbdefaultcharset=utf8;
Query OK,0rows affected (0.03 sec)

mysql>desc students;+-------+------------------+------+-----+---------+----------------+| 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||| email |varchar(20)| YES  ||NULL||+-------+------------------+------+-----+---------+----------------+4rowsinset(0.00 sec)

单行数据 + 全列插入

插入两条记录,当value_list 数量和定义表的列的数量及顺序一致时,就可以省略value_list。注意,这里在插入的时候,也可以不用指定id,mysql会使用默认的值进行自增。

mysql>insertinto students values(100,1000,'Curry',NULL);
Query OK,1row affected (0.01 sec)

mysql>insertinto students values(101,1001,'Durant','[email protected]');
Query OK,1row affected (0.00 sec)

mysql>select*from students;+-----+------+--------+--------------+| id  | sn   | name   | email        |+-----+------+--------+--------------+|100|1000| Curry  |NULL||101|1001| Durant |[email protected]|+-----+------+--------+--------------+2rowsinset(0.00 sec)

多行数据 + 指定列插入

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

mysql>insertinto students (id, sn, name)values(102,1002,'Kobe'),(103,1003,'Klay');
Query OK,2rows affected (0.00 sec)
Records: 2  Duplicates: 0Warnings: 0

mysql>select*from students;+-----+------+--------+--------------+| id  | sn   | name   | email        |+-----+------+--------+--------------+|100|1000| Curry  |NULL||101|1001| Durant |[email protected]||102|1002| Kobe   |NULL||103|1003| Klay   |NULL|+-----+------+--------+--------------+4rowsinset(0.00 sec)

插入否则更新

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

主键冲突:

mysql>insertinto students (id, sn, name)values(100,1004,'Brown');
ERROR 1062(23000): Duplicate entry '100'forkey'PRIMARY'

唯一键冲突:

mysql>insertinto students (id, sn, name)values(104,1003,'Bryant');
ERROR 1062(23000): Duplicate entry '1003'forkey'sn'

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

INSERT...ONDUPLICATEKEYUPDATEcolumn=value[,column=value]...
mysql>insertinto students (id, sn, name)values(104,1003,'Bryant')->onduplicatekeyupdate id=104, name='Bryant';
Query OK,2rows affected (0.01 sec)

mysql>select*from students;+-----+------+--------+--------------+| id  | sn   | name   | email        |+-----+------+--------+--------------+|100|1000| Curry  |NULL||101|1001| Durant |[email protected]||102|1002| Kobe   |NULL||104|1003| Bryant |NULL|+-----+------+--------+--------------+4rowsinset(0.00 sec)
  • 0 row affected: 表中有冲突数据,但冲突数据的值和 update 的值相等
  • 1 row affected: 表中没有冲突数据,数据被插入
  • 2 row affected: 表中有冲突数据,并且数据已经被更新

替换

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

mysql>replaceinto students (sn, name)values(1002,'Mitchell');
Query OK,2rows affected (0.00 sec)

mysql>select*from students;+-----+------+----------+--------------+| id  | sn   | name     | email        |+-----+------+----------+--------------+|100|1000| Curry    |NULL||101|1001| Durant   |[email protected]||104|1003| Bryant   |NULL||105|1002| Mitchell |NULL|+-----+------+----------+--------------+4rowsinset(0.00 sec)
  • 1 row affected: 表中没有冲突数据,数据被插入
  • 2 row affected: 表中有冲突数据,删除后重新插入

Retrieve(读取)

基础语法:

SELECT[DISTINCT] {*| {column[,column]...}
    [FROM table_name][WHERE...][ORDERBYcolumn[ASC|DESC],...]LIMIT...

案例:

创建表结构:

mysql>createtable exam_result (-> id intunsignedprimarykeyauto_increment,-> name varchar(20)notnullcomment'姓名',-> chinese floatdefault0.0comment'语文成绩',-> math floatdefault0.0comment'数学成绩',-> english floatdefault0.0comment'英语成绩'->)engine=innodbdefaultcharset=utf8;
Query OK,0rows affected (0.02 sec)

插入测试数据:

mysql>insertinto 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,7rows affected (0.00 sec)
Records: 7  Duplicates: 0Warnings: 0

SELECT列

全列查询

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

  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|+----+-----------+---------+------+---------+7rowsinset(0.00 sec)

指定列查询

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

mysql>select id, name, math from exam_result;+----+-----------+------+| id | name      | math |+----+-----------+------+|1| 唐三藏    |98||2| 孙悟空    |78||3| 猪悟能    |98||4| 曹孟德    |84||5| 刘玄德    |85||6| 孙权      |73||7| 宋公明    |65|+----+-----------+------+7rowsinset(0.00 sec)

查询字段为表达式

表达式不包含字段:

mysql>select id, name,10from exam_result;+----+-----------+----+| id | name      |10|+----+-----------+----+|1| 唐三藏    |10||2| 孙悟空    |10||3| 猪悟能    |10||4| 曹孟德    |10||5| 刘玄德    |10||6| 孙权      |10||7| 宋公明    |10|+----+-----------+----+7rowsinset(0.00 sec)

表达式包含一个字段:

mysql>select id, name, math+10from exam_result;+----+-----------+---------+| id | name      | math+10|+----+-----------+---------+|1| 唐三藏    |108||2| 孙悟空    |88||3| 猪悟能    |108||4| 曹孟德    |94||5| 刘玄德    |95||6| 孙权      |83||7| 宋公明    |75|+----+-----------+---------+7rowsinset(0.00 sec)

表达式包含多个字段:

mysql>select id, name, math+chinese+english from exam_result;+----+-----------+----------------------+| id | name      | math+chinese+english |+----+-----------+----------------------+|1| 唐三藏    |221||2| 孙悟空    |242||3| 猪悟能    |276||4| 曹孟德    |233||5| 刘玄德    |185||6| 孙权      |221||7| 宋公明    |170|+----+-----------+----------------------+7rowsinset(0.00 sec)

查询结果指定别名

基础语法:

ELECT column[AS] alias_name [...]FROM table_name;
mysql>select id, name, math+chinese+english total from exam_result;+----+-----------+-------+| id | name      | total |+----+-----------+-------+|1| 唐三藏    |221||2| 孙悟空    |242||3| 猪悟能    |276||4| 曹孟德    |233||5| 刘玄德    |185||6| 孙权      |221||7| 宋公明    |170|+----+-----------+-------+7rowsinset(0.00 sec)

结果去重

查询结果重复:

mysql>select math from exam_result;+------+| math |+------+|98||78||98||84||85||73||65|+------+7rowsinset(0.00 sec)

查询结果去重:

mysql>selectdistinct math from exam_result;+------+| math |+------+|98||78||84||85||73||65|+------+6rowsinset(0.00 sec)

WHERE 条件

基本比较

英语不及格的同学及英语成绩 ( < 60 ):

mysql>select name, english from exam_result where english<60;+-----------+---------+| name      | english |+-----------+---------+| 唐三藏    |56|| 刘玄德    |45|| 宋公明    |30|+-----------+---------+3rowsinset(0.00 sec)

BETWEEN AND 条件连接

语文成绩在 [80, 90] 分的同学及语文成绩:

使用 AND 进行条件连接

mysql>select name, chinese from exam_result where chinese>=80and chinese<=90;+-----------+---------+| name      | chinese |+-----------+---------+| 孙悟空    |87|| 猪悟能    |88|| 曹孟德    |82|+-----------+---------+3rowsinset(0.00 sec)

使用 BETWEEN AND 条件连接

mysql>select name, chinese from exam_result where chinese between80and90;+-----------+---------+| name      | chinese |+-----------+---------+| 孙悟空    |87|| 猪悟能    |88|| 曹孟德    |82|+-----------+---------+3rowsinset(0.00 sec)

OR 条件连接

数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩:

mysql>select name, math from exam_result where math=58or math=59or math=98or math=99;+-----------+------+| name      | math |+-----------+------+| 唐三藏    |98|| 猪悟能    |98|+-----------+------+2rowsinset(0.00 sec)

IN 条件连接

数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩:

mysql>select name, math from exam_result where math in(58,59,98,99);+-----------+------+| name      | math |+-----------+------+| 唐三藏    |98|| 猪悟能    |98|+-----------+------+2rowsinset(0.00 sec)

LIKE 条件匹配

查找姓孙的同学:% 匹配任意多个(包括 0 个)任意字符

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

查找孙某同学: _ 匹配严格的一个任意字符

mysql>select name from exam_result where name like'孙_';+--------+| name   |+--------+| 孙权   |+--------+1rowinset(0.00 sec)

WHERE 条件中使用表达式

总分在 200 分以下的同学:

mysql>select name, chinese+math+english total from exam_result where total<200;
ERROR 1054(42S22): Unknown column'total'in'where clause'

这里我们发现一个问题,where条件查询中不能使用指定别名,这是因为

chinese+math+english

这个字句比

where total<200

字句先执行,所以MySQL并不认识total这个别名,就会报错。

正确写法:

mysql>select name, chinese+math+english total from exam_result where chinese+math+english<200;+-----------+-------+| name      | total |+-----------+-------+| 刘玄德    |185|| 宋公明    |170|+-----------+-------+2rowsinset(0.00 sec)

AND 与 NOT 的使用

语文成绩 > 80 并且不姓孙的同学:

mysql>select name,chinese from exam_result where chinese>80and name notlike'孙%';+-----------+---------+| name      | chinese |+-----------+---------+| 猪悟能    |88|| 曹孟德    |82|+-----------+---------+2rowsinset(0.00 sec)

综合性查询

查询孙某同学,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80:

mysql>select name,chinese,math,english,chinese+math+english total from exam_result
    ->where(name like'孙_')or(chinese+math+english>200and chinese<math and english>80);+-----------+---------+------+---------+-------+| name      | chinese | math | english | total |+-----------+---------+------+---------+-------+| 猪悟能    |88|98|90|276|| 孙权      |70|73|78|221|+-----------+---------+------+---------+-------+2rowsinset(0.00 sec)

NULL的查询

查询 email 号已知的同学姓名:

mysql>select name from students where email isnotnull;+--------+| name   |+--------+| Durant |+--------+1rowinset(0.00 sec)

NULL 和 NULL 的比较,= 和 <=> 的区别:

mysql>selectNULL=NULL,NULL=1,NULL=0;+-----------+--------+--------+|NULL=NULL|NULL=1|NULL=0|+-----------+--------+--------+|NULL|NULL|NULL|+-----------+--------+--------+1rowinset(0.00 sec)

mysql>selectNULL<=>NULL,NULL<=>1,NULL<=>0;+-------------+----------+----------+|NULL<=>NULL|NULL<=>1|NULL<=>0|+-------------+----------+----------+|1|0|0|+-------------+----------+----------+1rowinset(0.00 sec)

结果排序

基本语法:

-- ASC 为升序(从小到大)-- DESC 为降序(从大到小)-- 默认为 ASCSELECT...FROM table_name [WHERE...]ORDERBYcolumn[ASC|DESC],[...];

升序显示

查询姓名及数学成绩,按数学成绩升序显示:

mysql>select name,math from exam_result orderby math;+-----------+------+| name      | math |+-----------+------+| 宋公明    |65|| 孙权      |73|| 孙悟空    |78|| 曹孟德    |84|| 刘玄德    |85|| 唐三藏    |98|| 猪悟能    |98|+-----------+------+7rowsinset(0.00 sec)

降序排序

查询姓名 及 eamil,按 eamil排序显示:

mysql>select name,email from students orderby email;+----------+--------------+| name     | email        |+----------+--------------+| Curry    |NULL|| Bryant   |NULL|| Mitchell |NULL|| Durant   |[email protected]|+----------+--------------+4rowsinset(0.00 sec)

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


多字段排序

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

mysql>select name,chinese,math,english from exam_result orderby math desc, english asc, chinese 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|+-----------+---------+------+---------+7rowsinset(0.00 sec)

多字段排序,排序优先级随书写顺序


ORDER BY 使用表达式

查询同学及总分,由高到低:

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

ORDER BY 子句中可以使用列别名:

mysql>select name, chinese+math+english total from exam_result orderby total desc;+-----------+-------+| name      | total |+-----------+-------+| 猪悟能    |276|| 孙悟空    |242|| 曹孟德    |233|| 唐三藏    |221|| 孙权      |221|| 刘玄德    |185|| 宋公明    |170|+-----------+-------+7rowsinset(0.00 sec)

结合 WHERE 子句 和 ORDER BY 子句

查询姓孙的同学或者姓曹的同学数学成绩,结果按数学成绩由高到低显示:

mysql>select name,math from exam_result where name like'孙%'or name like'曹%'orderby math desc;+-----------+------+| name      | math |+-----------+------+| 曹孟德    |84|| 孙悟空    |78|| 孙权      |73|+-----------+------+3rowsinset(0.00 sec)

筛选分页结果

基础语法:

-- 起始下标为 0-- 从 0 开始,筛选 n 条结果SELECT...FROM table_name [WHERE...][ORDERBY...]LIMIT n;-- 从 s 开始,筛选 n 条结果SELECT...FROM table_name [WHERE...][ORDERBY...]LIMIT s, n;-- 从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用SELECT...FROM table_name [WHERE...][ORDERBY...]LIMIT n OFFSET s;

建议:对未知表进行查询时,最好加一条 LIMIT 1,避免因为表中数据过大,查询全表数据导致数据库卡死按 id 进行分页,每页 3 条记录,分别显示 第 1、2、3 页。

案例:第 1 页:

mysql>select id, name, chinese, math, english from exam_result orderby id limit3offset0;+----+-----------+---------+------+---------+| id | name      | chinese | math | english |+----+-----------+---------+------+---------+|1| 唐三藏    |67|98|56||2| 孙悟空    |87|78|77||3| 猪悟能    |88|98|90|+----+-----------+---------+------+---------+3rowsinset(0.00 sec)

第 2 页:

mysql>select id, name, chinese, math, english from exam_result orderby id limit3offset3;+----+-----------+---------+------+---------+| id | name      | chinese | math | english |+----+-----------+---------+------+---------+|4| 曹孟德    |82|84|67||5| 刘玄德    |55|85|45||6| 孙权      |70|73|78|+----+-----------+---------+------+---------+3rowsinset(0.00 sec)

第 3 页,如果结果不足 3 个,不会有影响:

mysql>select id, name, chinese, math, english from exam_result orderby id limit3offset6;+----+-----------+---------+------+---------+| id | name      | chinese | math | english |+----+-----------+---------+------+---------+|7| 宋公明    |75|65|30|+----+-----------+---------+------+---------+1rowinset(0.00 sec)

Update(更新)

基本语法:

UPDATE table_name SETcolumn= expr [,column= expr ...][WHERE...][ORDERBY...][LIMIT...]

更新单列

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

mysql>select name, math from exam_result where name='孙悟空';+-----------+------+| name      | math |+-----------+------+| 孙悟空    |78|+-----------+------+1rowinset(0.00 sec)

mysql>update exam_result set math=80where name='孙悟空';
Query OK,1row affected (0.01 sec)Rowsmatched: 1  Changed: 1Warnings: 0

mysql>select name, math from exam_result where name='孙悟空';+-----------+------+| name      | math |+-----------+------+| 孙悟空    |80|+-----------+------+1rowinset(0.00 sec)

更新多列

将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分:

mysql>select name, math, chinese from exam_result where name='曹孟德';+-----------+------+---------+| name      | math | chinese |+-----------+------+---------+| 曹孟德    |84|82|+-----------+------+---------+1rowinset(0.00 sec)

mysql>update exam_result set math=60, chinese=70where name='曹孟德';
Query OK,1row affected (0.00 sec)Rowsmatched: 1  Changed: 1Warnings: 0

mysql>select name, math, chinese from exam_result where name='曹孟德';+-----------+------+---------+| name      | math | chinese |+-----------+------+---------+| 曹孟德    |60|70|+-----------+------+---------+1rowinset(0.00 sec)

更新值为原值基础上变更

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

mysql>update exam_result set math=math+30orderby chinese+math+english limit3;
Query OK,3rows affected (0.00 sec)Rowsmatched: 3  Changed: 3Warnings: 0

mysql>select name, math from exam_result;+-----------+------+| name      | math |+-----------+------+| 唐三藏    |98|| 孙悟空    |80|| 猪悟能    |98|| 曹孟德    |90|| 刘玄德    |115|| 孙权      |73|| 宋公明    |95|+-----------+------+7rowsinset(0.00 sec)

更新全表

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

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

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

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

Delete(删除)

基础语法:

DELETEFROM table_name [WHERE...][ORDERBY...][LIMIT...]

删除单条记录

删除孙悟空同学的考试成绩:

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

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

mysql>select*from exam_result where name='孙悟空';
Empty set(0.00 sec)

删除整表

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

准备测试表:

mysql>createtable for_delete (-> id intunsignedprimarykeyauto_increment,-> name varchar(20)->)engine=innodbdefaultcharset=utf8;
Query OK,0rows affected (0.02 sec)

插入测试数据:

mysql>insertinto for_delete (name)values('a'),('b'),('c');
Query OK,3rows affected (0.00 sec)
Records: 3  Duplicates: 0Warnings: 0

mysql>select*from for_delete;+----+------+| id | name |+----+------+|1| a    ||2| b    ||3| c    |+----+------+3rowsinset(0.00 sec)

删除整表数据:

mysql>deletefrom for_delete;
Query OK,3rows affected (0.00 sec)

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

再插入一条数据,自增 id 在原值上增长:

mysql>insertinto for_delete (name)values('d');
Query OK,1row affected (0.00 sec)

mysql>select*from for_delete;+----+------+| id | name |+----+------+|4| d    |+----+------+1rowinset(0.00 sec)

查看表结构,会有 AUTO_INCREMENT=n 项:

mysql>showcreatetable for_delete \G
***************************1.row***************************Table: for_delete
CreateTable: CREATETABLE`for_delete`(`id`int(10)unsignedNOTNULLAUTO_INCREMENT,`name`varchar(20)DEFAULTNULL,PRIMARYKEY(`id`))ENGINE=InnoDBAUTO_INCREMENT=5DEFAULTCHARSET=utf8
1rowinset(0.00 sec)

说明:虽然delete语句删除了整表,但是再向删除后的表插入时,表中的自增值会在之前的原数据的基础之上增加。


截断表

基础语法:

TRUNCATE[TABLE] table_name
  1. TRUNCATE 只能对整表操作,不能像 DELETE 一样针对部分数据操作;
  2. 实际上 MySQL 不对数据操作,所以比 DELETE 更快,但是TRUNCATE在删除数据的时候,并不经过真正的事物,所以无法回滚
  3. 会重置 AUTO_INCREMENT 项

准备测试表:

mysql>createtable for_truncate (-> id intunsignedprimarykeyauto_increment,-> name varchar(20)->)engine=innodbdefaultcharset=utf8;
Query OK,0rows affected (0.02 sec)

插入测试数据:

mysql>insertinto for_truncate (name)values('a'),('b'),('c');
Query OK,3rows affected (0.00 sec)
Records: 3  Duplicates: 0Warnings: 0

mysql>select*from for_truncate;+----+------+| id | name |+----+------+|1| a    ||2| b    ||3| c    |+----+------+3rowsinset(0.00 sec)

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

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

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

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

mysql>insertinto for_truncate (name)values('d');
Query OK,1row affected (0.00 sec)

mysql>select*from for_truncate;+----+------+| id | name |+----+------+|1| d    |+----+------+1rowinset(0.00 sec)

查看表结构,会有 AUTO_INCREMENT=2 项:

mysql>showcreatetable for_truncate \G
***************************1.row***************************Table: for_truncate
CreateTable: CREATETABLE`for_truncate`(`id`int(10)unsignedNOTNULLAUTO_INCREMENT,`name`varchar(20)DEFAULTNULL,PRIMARYKEY(`id`))ENGINE=InnoDBAUTO_INCREMENT=2DEFAULTCHARSET=utf8
1rowinset(0.00 sec)

插入查询结果

基础语法:

INSERTINTO table_name [(column[,column...])]SELECT...

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

创建原数据表,插入测试数据:

mysql>createtable duplicate_table (-> id int,-> name varchar(20)->);
Query OK,0rows affected (0.04 sec)

mysql>insertinto duplicate_table values->(100,'aaa'),->(100,'aaa'),->(200,'bbb'),->(200,'bbb'),->(200,'bbb'),->(300,'ccc');
Query OK,6rows affected (0.00 sec)
Records: 6  Duplicates: 0Warnings: 0

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

mysql>createtable no_duplicate_table like duplicate_table;
Query OK,0rows affected (0.01 sec)

mysql>desc no_duplicate_table;+-------+-------------+------+-----+---------+-------+| Field |Type|Null|Key|Default| Extra |+-------+-------------+------+-----+---------+-------+| id    |int(11)| YES  ||NULL||| name  |varchar(20)| YES  ||NULL||+-------+-------------+------+-----+---------+-------+2rowsinset(0.00 sec)

将 duplicate_table 的去重数据插入到 no_duplicate_table:

mysql>insertinto no_duplicate_table selectdistinct*from duplicate_table;
Query OK,3rows affected (0.00 sec)
Records: 3  Duplicates: 0Warnings: 0

mysql>select*from no_duplicate_table;+------+------+| id   | name |+------+------+|100| aaa  ||200| bbb  ||300| ccc  |+------+------+3rowsinset(0.00 sec)

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

mysql>altertable duplicate_table renameto duplicate_table_bak;
Query OK,0rows affected (0.00 sec)

mysql>altertable no_duplicate_table renameto duplicate_table;
Query OK,0rows affected (0.01 sec)

聚合函数

在这里插入图片描述

案例:

统计班级共有多少同学:

mysql>selectcount(*)from students;+----------+|count(*)|+----------+|4|+----------+1rowinset(0.00 sec)

统计班级收集的 email 有多少:

mysql>selectcount(email)from students;+--------------+|count(email)|+--------------+|1|+--------------+1rowinset(0.00 sec)

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

统计全部成绩:

mysql>selectcount(math)from exam_result;+-------------+|count(math)|+-------------+|6|+-------------+1rowinset(0.00 sec)

统计去重成绩数量:

mysql>selectcount(distinct math)from exam_result;+----------------------+|count(distinct math)|+----------------------+|5|+----------------------+1rowinset(0.00 sec)

统计数学成绩总分:

mysql>selectsum(math)from exam_result;+-----------+|sum(math)|+-----------+|569|+-----------+1rowinset(0.00 sec)

统计平均总分:

mysql>selectavg(chinese+math+english)from exam_result;+---------------------------+|avg(chinese+math+english)|+---------------------------+|297.5|+---------------------------+1rowinset(0.00 sec)

返回英语最高分:

mysql>selectmax(english)from exam_result;+--------------+|max(english)|+--------------+|90|+--------------+1rowinset(0.00 sec)

返回 > 70 分以上的数学最低分:

mysql>selectmin(math)from exam_result where math>70;+-----------+|min(math)|+-----------+|73|+-----------+1rowinset(0.00 sec)

group by子句的使用

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

基本语法:

select column1, column2,..fromtablegroupbycolumn;

案例:

准备工作,创建一个雇员信息表

  • EMP员工表
  • DEPT部门表
  • SALGRADE工资等级表
mysql>desc dept;+--------+--------------------------+------+-----+---------+-------+| Field  |Type|Null|Key|Default| Extra |+--------+--------------------------+------+-----+---------+-------+| deptno |int(2)unsigned zerofill |NO||NULL||| dname  |varchar(14)| YES  ||NULL||| loc    |varchar(13)| YES  ||NULL||+--------+--------------------------+------+-----+---------+-------+3rowsinset(0.00 sec)

mysql>desc emp;+----------+--------------------------+------+-----+---------+-------+| Field    |Type|Null|Key|Default| Extra |+----------+--------------------------+------+-----+---------+-------+| empno    |int(6)unsigned zerofill |NO||NULL||| ename    |varchar(10)| YES  ||NULL||| job      |varchar(9)| YES  ||NULL||| mgr      |int(4)unsigned zerofill | YES  ||NULL||| hiredate |datetime| YES  ||NULL||| sal      |decimal(7,2)| YES  ||NULL||| comm     |decimal(7,2)| YES  ||NULL||| deptno   |int(2)unsigned zerofill | YES  ||NULL||+----------+--------------------------+------+-----+---------+-------+8rowsinset(0.00 sec)

mysql>desc salgrade;+-------+---------+------+-----+---------+-------+| Field |Type|Null|Key|Default| Extra |+-------+---------+------+-----+---------+-------+| grade |int(11)| YES  ||NULL||| losal |int(11)| YES  ||NULL||| hisal |int(11)| YES  ||NULL||+-------+---------+------+-----+---------+-------+3rowsinset(0.00 sec)

显示每个部门的平均工资和最高工资:

mysql>select deptno,avg(sal) avg,max(sal) max from emp groupby deptno;+--------+-------------+---------+| deptno | avg         | max     |+--------+-------------+---------+|10|2916.666667|5000.00||20|2175.000000|3000.00||30|1566.666667|2850.00|+--------+-------------+---------+3rowsinset(0.00 sec)

每个部门的每种岗位的平均工资和最低工资:

mysql>select deptno, job,avg(sal) avg,min(sal) min from emp groupby deptno, job;+--------+-----------+-------------+---------+| deptno | job       | avg         | min     |+--------+-----------+-------------+---------+|10| CLERK     |1300.000000|1300.00||10| MANAGER   |2450.000000|2450.00||10| PRESIDENT |5000.000000|5000.00||20| ANALYST   |3000.000000|3000.00||20| CLERK     |950.000000|800.00||20| MANAGER   |2975.000000|2975.00||30| CLERK     |950.000000|950.00||30| MANAGER   |2850.000000|2850.00||30| SALESMAN  |1400.000000|1250.00|+--------+-----------+-------------+---------+9rowsinset(0.00 sec)

平均工资低于2000的部门和它的平均工资:

mysql>select deptno,avg(sal) avg from emp groupby deptno having avg <2000;+--------+-------------+| deptno | avg         |+--------+-------------+|30|1566.666667|+--------+-------------+1rowinset(0.00 sec)

having经常和group by搭配使用,作用是对分组进行筛选,作用有些像where,但是having通常在数据where选择完,group by进行分组,再执行having筛选。


标签: mysql 数据库 sql

本文转载自: https://blog.csdn.net/weixin_53027918/article/details/128810632
版权归原作者 还小给个面子 所有, 如有侵权,请联系我们删除。

“MySQL基本查询”的评论:

还没有评论