语法:
INSERT [INTO] table_name
[(column [, column] ...)]
VALUES (value_list) [, (value_list)] ...
value_list: value, [, value] ...
单行指定列插入:

单行全列插入:

into也可以省略:

多行全列插入:

多行指定列插入:

我们知道,如果发生主键或者唯一键冲突的时候,会报错。但是如果就是想要修改原来的数据呢?可以选择性的进行同步更新操作语法。
语法:
INSERT ... ON DUPLICATE KEY UPDATE
column = value [, column = value] ...
而对于 x rows affected有下面的解释:
通过 MySQL 函数获取受到影响的数据行数:
SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
| 2 |
+-------------+如果要插入的值在原数据中并没有,则相当于正常插入语句。

如果我们想更新原数据,但是连着运行了两次命令,则第一次正常修改,第二次并不会改变什么。

-- 主键 或者 唯一键 没有冲突,则直接插入;
-- 主键 或者 唯一键 如果冲突,则删除后再插入
REPLACE INTO students (sn, name) VALUES (20001, '曹阿瞒');
Query OK, 2 rows affected (0.00 sec)
-- 1 row affected: 表中没有冲突数据,数据被插入
-- 2 row affected: 表中有冲突数据,删除后重新插入
并且可以看到id是变了的。
语法:
SELECT
[DISTINCT] {* | {column [, column] ...}
[FROM table_name]
[WHERE ...]
[ORDER BY column [ASC | DESC], ...]
LIMIT ... 
//通常情况下不建议使用*进行全列查询 //1.查询的列越多,意味着需要传输的数据量越大 //2.可能会影响索引的使用

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

select后面也可以接表达式。

语法:
SELECT column [AS] alias_name [...] FROM table_name; 
也可以省略as:

使用关键字distinct去重:

比较运算符:
运算符 | 说明 |
|---|---|
>,>=, | 大于,大于等于,小于,小于等于 |
= | 等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL |
<=> | 等于,NULL 安全,例如 NULL NULL 的结果是 TRUE(1) |
!=,<> | 不等于 |
BETWEEN a0 AND a1 | 范围匹配,[a0, a1],如果 a0 |
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) |






而对于下面这种报错:

涉及到执行顺序的问题:

上面语句是按照ABC的顺序执行,所以在执行B的时候还没有total的定义,所以显示unknown。
并且不能再筛选条件处做重命名:




''不等于NULL
语法:
-- ASC 为升序(从小到大)
-- DESC 为降序(从大到小)
-- 默认为 ASC
SELECT ... FROM table_name [WHERE ...]
ORDER BY column [ASC|DESC], [...]; 注意:没有 ORDER BY 子句的查询,返回的顺序是未定义的,永远不要依赖这个顺序。

默认是升序的。

如果有NULL,则NULL视作比任何值都小,升序出现在最上面,降序出现在最下面。



order by中可以使用表达式。

order by中可以使用列别名,这是区别于where的地方。
因为:



语法:
-- 起始下标为 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,避免因为表中数据过大,查询全表数据导致数据库卡死。
那么limit有什么用呢?可以进行简单的分页操作。
例如:按id进行分页,每页3条记录,分别显示第1、2、3页。
第一页:

第二页:

第三页:

那么我们再来看看子语句的顺序:

语法:
UPDATE table_name SET column = expr [, column = expr ...]
[WHERE ...] [ORDER BY ...] [LIMIT ...] 对查询到的结果进行列值更新。意思就是先进行查询,再进行列值更新。



注意:更新全表的语句慎用!!!

语法:
DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...] 
也可以接order by,例如删除排名最后的一名:

注意:删除整表操作要慎用!!!
并且MySQL中,表分为表本身和表中的数据。删除整张表删除的是表中的数据,并不影响表结构,修改表结构用alter。


delete整张表并不会清空自增序列的值。

语法:
TRUNCATE [TABLE] table_name 注意:这个操作慎用
例子:


语法:
INSERT INTO table_name [(column [, column ...])] SELECT ... 例子:删除表中的的重复复记录,重复的数据只能有一份

函数 | 说明 |
|---|---|
COUNT([DISTINCT] expr) | 返回查询到的数据的 数量 |
SUM([DISTINCT] expr) | 返回查询到的数据的 总和,不是数字没有意义 |
AVG([DISTINCT] expr) | 返回查询到的数据的 平均值,不是数字没有意义 |
MAX([DISTINCT] expr) | 返回查询到的数据的 最大值,不是数字没有意义 |
MIN([DISTINCT] expr) | 返回查询到的数据的 最小值,不是数字没有意义 |







在select中使用group by 子句可以对指定列进行分组查询:
select column1, column2, .. from table group by column; 分组的目的是为了进行分组之后,方便进行聚合统计。
例子:
创建库的文件,在文章开头的资源中给出,下载scott_data即可:

下载后,上传到Linux平台,然后登陆数据库。
create database 数据库名;use 数据库名;将刚才上传到服务器的sql文件导入(我服务器中sql文件路径是root/scott_data.sql)
source /root/scott_data.sqlemp员工表:

dept部门表:

salgrade工资等级表:






having经常和group by搭配使用,作用是对分组进行筛选,作用有些像where。
但是having与where是有区别的,不建议混用:

不要单纯的认为,只有磁盘上的表结构导入到mysql,真实存在的表,才叫做表。 中间筛选出来的,包括最终结果,在我看来,全部都是逻辑上的表!“MySQL一切皆表”。 未来只要我们处理好单表的CURD,所有的sql场景,我们全部都能用统一的方式进行。
总结:
好了,到这里今天的知识就讲完了,大家有错误一点要在评论指出,我怕我一人搁这瞎bb,没人告诉我错误就寄了。
祝大家越来越好,不用关注我(疯狂暗示)