CRUD:Create(创建),Retrieve(读取),Update(更新),Delete(删除)。
insert [into] table_name [(column [, column] ...)] values (value_list) [, (value_list)] ...
value_list: value, [, value] ...
values 左侧括号内是列属性,右侧括号内是列属性对应的内容,必须在类型和数值上一一对应。
若忽略 values 左侧括号内的内容,则称为全列插入,否则成为按列插入。
创建一张学生表:
insert ... on duplicate key update column=value [, column = value] ...
- 0 row affected:表中有冲突数据,但冲突数据的值和 update 的值相等。
- 1 row affected:表中没有冲突数据,数据被插入。
- 2 row affected:表中有冲突数据,并且数据已经被更新。
- 1 row affected:表中没有冲突数据,数据被插入。
- 2 row affected:表中有冲突数据,删除后重新插入。
select [distinct] {* | {column [, column] ...} [from table_name] [where ...] [order by column [asc | desc], ...] limit ...
- 查询的列越多,意味着需要传输的数据量越大。
- 可能会影响到索引的使用。
通常情况下不建议使用 * 进行全列查询。
指定列的顺序不需要按定义表的顺序来。
select column [as] alias_name [...] from table_name;
注意:在 MySQL 中, 用 = 来判断两个 字符串或数字 是否相等,与 C/C++ 不同。 用 = 判断是否等于 NULL 这样做是不安全的,因为 NULL 和 0 本身表示的含义不同,NULL 表示空,0 表示数字 0。
写法一:
where 条件中使用表达式,别名不能用在 where 条件中。
错误写法:
综合性查询
SELECT NULL <=> NULL, NULL <=> 1, NULL <=> 0
- ASC 为升序(从小到大)
- DESC 为降序(从大到小)
默认为 ASC。
注意:没有 ORDER BY 子句的查询,返回的顺序是未定义的,永远不要依赖这个顺序。
select ... from table_name [where ...] order by column [asc|desc], [...] ;
- NULL 视为比任何值都小,升序出现在最上面。
- NULL 视为比任何值都小,降序出现在最下面。
asc 可以省略不写,但不建议。
能否使用别名完全取决于当前 sql 子句的执行顺序。
order by 中可以使用表达式。
order by 子句的执行顺序晚于 where 子句。
建议:对未知表进行查询时,最好加一条 limit 1 ,避免因为表中数据过大,查询全表数据导致数据库卡死。 按 id 进行分页,每页 3 条记录,分别显示 第 1 、 2 、 3 页。
- 从 0 开始,筛选 n 条结果 select ... from table_name [where ...] [order by ...] limit n; 3:从表开始()开始连续读取 3 行。
从 s 开始,筛选 n 条结果 select ... from table_name [where ...] [order by ...] limit s, n; 1:开始位置(下标从 0 开始)。 3:步长,从指定位置开始,连续读取 3 条记录。
从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用 select ... from table_name [where ...] [order by ...] limit n offset s; 4:步长,从指定位置开始,连续读取 4 条记录。 1:开始位置(下标从 0 开始)。 注意 :起始下标为 0。
只有数据准备好了,才要显示,limit 的本质功能是 “显示”。
得先有数据,才能 “显示”,“显示” 时,limit 只是告诉 MySQL,显示时只显示从哪里开始,从开始位置显示几行。
limit 不是条件筛选,本质就是把数据准备好,排好序,然后再 limit,执行阶段更靠后。
update table_name set column=expr [, column = expr ...] [where ...] [order by ...] [limit ...]
对查询到的结果进行列值更新。
注意:别名可以在 order by 中使用 。
注意 :更新全表的语句慎用。
delete from table_name [where ...] [order by ...] [limit ...];
注意 :删除整表操作要慎用。
truncate [table] table_name;
再插入一条数据,自增 id 再重新增长
delete 和 truncate 的区别:
注意 :这个操作慎用。
- 都可以清空表中的数据。
- delete from 是传统的删除,不会对计数器进行清空或重新置位,而 truncate 清空表会重置 auto_increment 项。
- truncate 是直接将表中数据清空,它不走事务,而 delete from 以及之前学的 sql 最终在运行时都要以事务的方式被包装,然后再让 MySQL 去运行。
- 只能对整表操作,不能像 delete 一样针对部分数据操作。
- 实际上 MySQL 不对数据操作,所以比 delete 更快,但是 truncate 在删除数据时,并不经过真正的事物,所以无法回滚。
- 会重置 auto_increment 项。
insert into table_name [(column [, column ...])] select ...;
错误思路:
就是单纯的想等一切都就绪了,然后统一放入、更新、生效等。
count(math) 统计的是全部成绩
注意:
distinct 要写在括号内,因为我们是要对 math 去重,而不是对 count() 的结果去重。
NULL 不会计入结果。
分组的目的:为了进行分组后,方便进行聚合统计。
在 select 中使用 group by 子句可以对指定列进行分组查询:
select column1, column2, .. from table group by column;
指定列名,实际分组是用该列不同的行数来进行分组的。
分组的 deptno,组内一定是相同的。说明可以被聚合压缩。
分组就是把一组按照条件拆分成了多个组,进行各自组内的统计。
分组(“分表”),就是把一张表按照条件在逻辑上拆成了多个子表,然后分别对各自的子表进行聚合统计。
having 和 group by 的语义是一样的,having 相当于是对分组聚合统计后的数据,进行条件筛选。
having 经常和 group by 搭配使用,作用是对分组进行筛选,作用有些像 where。
都能够做条件筛选,这是它们的共性。
但它们是完全不同的条件筛选,它们的条件筛选的阶段是不同的。
补充:不要单纯的认为,只有在磁盘上将表结构导入到 MySQL,真实存在的表才叫表。
中间筛选出来的,包括最终结果,全都是逻辑上的表。(MySQL 一切皆表)
只要我们能够处理好单表的 CURD,所有的 sql 场景就都能用统一的方式进行。
SQL 查询中各个关键字的执行先后顺序:
from > on > join > where > group by > with > having > select > distinct > order by > limit