目录
[单行数据 + 指定列插入](#单行数据 + 指定列插入)
[单行数据 + 全列插入](#单行数据 + 全列插入)
[多行数据 + 全列插入](#多行数据 + 全列插入)
**表的增删查改:**CRUD : Create(创建), Retrieve(读取),Update(更新),Delete(删除)
Create(创建)
案例建表
mysql> create table if not exists students(
-> id int unsigned primary key auto_increment,
-> sn int not null unique key comment '学号',
-> name varchar(20) not null,
-> qq varchar(32)
-> );
插入
语法:INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...), (value1, value2, ...), ...;
INSERT INTO table_name
: 指定要插入数据的目标表名。(INTO可省略)(column1, column2, ...)
: 可选项,指定要插入数据的列名。如果省略列名,则假定将为所有列提供值。VALUES (value1, value2, ...), (value1, value2, ...), ...
: 指定要插入的值列表。每个value_list
都对应一个要插入的行,每个值按照与列的顺序匹配。(几个小括号就是几行插入)
可以理解为values左边是列属性,右边是列属性的内容 ;相当于扁担
单行数据 + 指定列插入
指定列单行插入:insert into students (sn,name,qq) values (123,'张飞','123456')
单行数据 + 全列插入
因为忽略了列属性所以不知道向哪里插入所以要每个列都插入即全列插入;
单行全列:insert into students values (2,124,'关于','123457');
多行数据 + 全列插入
多行插入:你可以单行重复多次插入,也可以直接多行插入;
多行全列插入 :insert into students values (3,125,'刘备','123458'),(4,126,'许褚','123459'),(5,127,'曹操','1234560');//用逗号分开表示多行
如果多行指定列插入的话:那么忽略的列必须要有默认值(default值)或者它是自增长;
插入是否更新
由于主键或者唯一键 对应的值已经存在而导致插入失败
主键冲突:mysql> insert into students values (1,128,'关于','123457');
报错:ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
唯一键冲突:mysql> insert into students values (6,124,'关于','123457');
报错:ERROR 1062 (23000): Duplicate entry '124' for key 'sn'
插入时更新
可以选择性的进行同步更新操作
插入:insert into students values (4,127,'xuyou','123123123') on duplicate key update sn=127,name='xuyou',qq='123123123';//如果碰到冲突了就执行update后面的语句
报错:ERROR 1062 (23000): Duplicate entry '127' for key 'sn'//因为sn唯一键冲突了
正确插入更新:insert into students values (4,128,'xuyou','123123123') on duplicate key update sn=128,name='xuyou',qq='123123123';
//on duplicate key update可以理解为如果冲突了就执行后续更新操作否则就不执行
如果遇到冲突了,那么执行update的数据,前提是update的值也不能冲突;当然也可以修改冲突的值:
mysql> insert into students values (4,128,'xuyou','123123123') on duplicate key update id=6,sn=128,name='xuyou',qq='123123123';
那么冲突的也修改了;
但是这条操作就不行,因为更新语句主键不冲突但是唯一键冲突:
mysql> insert into students values (6,128,'xuyou','123123123') on duplicate key update id=4,sn=123,name='xuyou',qq='123123123'; //sn与id=1的sn数据冲突
正确:mysql> insert into students values (6,128,'xuyou','123123123') on duplicate key update id=4,sn=128,name='xuyou',qq='123123123';
所以更新的唯一键要么不变要么不与其他冲突;当然也可以这样:
老数据与新数据一样,虽然冲突了但是没变;也是可以的;
插入成功后有提示:
当然也可以用函数查找受影响的行数(是上一个语句执行后受影响的行数) row_count()
错误语句:没有受影响(-1)
查数据:没有行受影响(-1)
插入冲突数据:显示影响行数
替换
对于replace:主键或者唯一键没有冲突,则直接插入;主键或者唯一键如果冲突,则删除后再插入;
插入不冲突的:replace into students (sn,name,qq) values (129,'霸王','123');
插入冲突:replace into students (sn,name,qq) values (131,'霸王2','123');
可以看到是先删除冲突的数据后再添加,由id的自增长可以看到;原来的10没了
Retrieve(读取)
建表插入
mysql> 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 '英语成绩'
-> );
mysql> 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);
select列
全列查询
通 常 情 况 下 不 建 议 使 用 * 进 行 全 列 查 询:
- 1 . 查 询 的 列 越 多 , 意 味 着 需 要 传 输 的 数 据 量 越 大 ;
- 2 . 可 能 会 影 响 到 索 引 的 使 用 。
未来我们的数据库服务是在远端的服务器上的;
select * from exam_result;//默认整张表的信息
指定列查询
select id from exam_result;//指定id列
select id,math,english from exam_result;//指定多个列
查询字段为表达式
mysql> select 1+1;
mysql> select 7*9;
mysql> select id,math,english,10 from exam_result;
mysql> select id,math+english,10 from exam_result;
为查询结果指定别名
mysql> select id,math+english as total from exam_result;
mysql> select id,math+english total from exam_result;//省略as也是可以的,一样结果
mysql> select name 姓名,math+english 总分 from exam_result;//多个别名,用逗号分隔
mysql> select 1+1 假发;
对哪一列起别名就在哪一列后面加别名;
结果去重
distinct:只能进行单列的去重挑选唯一值;
mysql> select distinct math from exam_result;//对那一列去重就在那一列前加distinct
错误多列去重:select distinct math,distinct english from exam_result;//不能多列去重
where条件
比较运算符
在MySQL中比较两个数字或者字符串是否相等 用的是一个等号 ;
在使用=时,不能使用NULL=NULL;不安全
正常情况下比较后是true(1)或者false(0),但是NULL=NULL不是而是NULL当然你可以这样:mysql> select NULL<=>NULL;//这样安全
<=>也可以使用数字或者字符串比较;
!=和<>同样无法比较NULL,可以比较数字与字符串
NULL不参与任何计算 ,任何数与null计算都是null
IS NULL
IS NOT NULL
逻辑运算符
案例
英语不及格的同学及英语成绩 ( < 60 ):
mysql> select english from exam_result where english<60;//使用比较运算符
语文成绩在 [80, 90] 分的同学及语文成绩mysql> select name,chinese from exam_result where chinese>=80 and chinese<=90;
//使用逻辑运算符与比较运算符
mysql> select name,chinese from exam_result where chinese between 80 and 90;使用between x and xx;本身就是闭区域
数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩mysql> select name,math from exam_result where math=58 or math=59 or math=98 or math=99;//使用比较和逻辑运算符
mysql> select name,math from exam_result where math in(58,59,98,99);//使用in只要满足in里面任意一个就为真;
姓孙的同学及孙某同学:模糊匹配 ( 姓孙可以是孙某也可以是孙某某或者孙某某某等**)**% 表示任意多个(包括 0 个)任意字符;_ 表示任意一个字符
姓孙:mysql> select name from exam_result where name like '孙%';
孙某:mysql> select name from exam_result where name like '孙_';
语文成绩好于英语成绩的同学mysql> select name,chinese,english from exam_result where chinese > english;
总分在 200 分以下的同学错误:mysql> select name,chinese+math+english total from exam_result where total <200;
ERROR 1054 (42S22): Unknown column 'total' in 'where clause'/ /别名不能用在 WHERE 条件中是先执行from exam_result然后执行where total <200语句最后执行select name,chinese+math+english total;但是在第二步就错了因为表中没有total列
正确:mysql> select name,chinese+math+english total from exam_result where chinese+math+english <200;
语文成绩 > 80 并且不姓孙的同学mysql> select name,chinese total from exam_result where chinese>80 and name not like '孙%';
孙某同学,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80mysql> select name,chinese,math,english,chinese+math+english total from exam_result where name like '孙_' or (chinese+math+english>200 and chinese<math and english>80);加小括号更准确
看name中是否有NULLmysql> select name from exam_result where name is null;
where可以理解为条件
结果排序
--ASC 为升序(从小到大)
-- DESC 为降序(从大到小)
-- 默认为 ASC
SELECT ... FROM table_name [WHERE ...] ORDER BY column [ASC|DESC], [...];
注意:没有 ORDER BY 子句的查询,返回的顺序是未定义的,永远不要依赖这个顺序
降序:mysql> select name,math from exam_result order by math desc;
升序:mysql> select name,math from exam_result order by math asc;
NULL 视为比任何值都小,升序出现在最上面 ;
NULL 视为比任何值都小,降序出现在最下面;
查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示
(多字段排序,排序优先级随书写顺序)
mysql> select name,math,english,chinese from exam_result order by math desc,english,chinese;//不写的话默认asc
如果数学成绩每个人都相等,那么就按照英语成绩的升序来完成,以此类推;
就比如唐三藏和猪悟能的数学成绩一样,那么就按照英语的升序排序比较;
查询同学及总分,由高到低ORDER BY 中可以使用表达式
mysql> select name,math+english+chinese total from exam_result order by math+english+chinese desc;
mysql> select name,math+english+chinese total from exam_result order by total desc;//可以使用别名为什么这里可以使用呢?因为先from exam_result然后条件where再选出select name,math+english+chinese total最后比较order by 四步操作顺序进行,所以能用别名
查询姓孙的同学或者姓曹的同学数学成绩,结果按数学成绩由高到低显示mysql> select name,math from exam_result where name like '孙%' or name like '曹%' order by math desc;
order by是有数据才能排序,先把数据按照条件筛选出来我才拍;
筛选分页结果
起始下标为 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;
n相当于步长;
从 0 开始,筛选 n 条结果:
mysql> select * from exam_result limit 5;//下标是0的位置是id=1,连续5个
mysql> select * from exam_result limit 3;//下标是0的位置是id=1,连续3个
从表开始(0)连续n行
从 s 开始,筛选n条结果:s指的是下标,这里id=1的下标是0mysql> select * from exam_result limit 1,3;//下标是1的位置是id=2,连续3个
mysql> select * from exam_result limit 2,3;//下标是2的位置是id=3,连续3个
从 s 开始,筛选 n 条结果:mysql> select * from exam_result limit 5 offset 0;
相当于mysql> select * from exam_result limit 5;
建议:对未知表进行查询时,最好加一条 LIMIT 1,避免因为表中数据过大,查询全表数据导致数据库卡死 按 id 进行分页,每页 3 条记录,分别显示 第 1、2、3 页
第一页mysql> select id,name,math,english,chinese from exam_result order by id limit 3 offset 0;
第二页mysql> select id,name,math,english,chinese from exam_result order by id limit 3 offset 3;
第三页mysql> select id,name,math,english,chinese from exam_result order by id limit 3 offset 6;
当然也可以结合where:mysql> select id,name,math+english+chinese total from exam_result where math+english+chinese>200 order by total limit 3 offset 0;
limit 就是你把数据准备好,按照条件筛选出再排序给我,我在"显示",limit执行靠后;