上篇文章,咱们介绍了数据的基本 DDL 语句,你应当具有基本的建立数据库、数据表的 SQL 语句,以及表字段的基本数据类型的熟知。java
那么本篇就来总结总结你们平常最频繁接触到的 DDM 语句,也就是基本的增删改查 SQL。git
众所周知的是,咱们的项目中,有百分之八十的操做都是在查询,而仅有百分之二十的操做是作的数据修改。程序员
因此,关系型数据库中对于数据的修改这块并无什么很复杂的门道,咱们优先介绍这一块内容,而对于数据的查询而言,它会复杂的多,各类排序、分组、子查询以及多表链接查询等等等等,就是旨在知足咱们多样化的查询需求以及提高查询效率,这个咱们稍后会介绍。github
数据的修改包括,数据的插入、数据的修改以及数据的删除。数据库
一、插入数据bash
向表中插入一条数据的 SQL 语法以下:微信
INSERT INTO [TABLE_NAME] (column1, column2, column3,...columnN)
VALUES (value1, value2, value3,...valueN);
复制代码
那好,咱们具体来看一个例子吧。函数
先建立这么一张 person 表,使用以下 SQL:学习
create table person(
id int primary key,
name varchar(16) not null,
age int,
phone varchar(11),
address varchar(256)
);
复制代码
接着,咱们插入一条数据:ui
insert into person(id,name,age,phone,address)
values (1,'yang',22,'123232323','中国上海');
复制代码
因而你查询 person 表,会看到
+----+------+------+-----------+--------------+
| id | name | age | phone | address |
+----+------+------+-----------+--------------+
| 1 | yang | 22 | 123232323 | 中国上海 |
+----+------+------+-----------+--------------+
复制代码
固然,若是你在插入数据时有些字段的值暂时不想传入,或是该字段有默认值,insert 语句是容许你部分数据插入的,前提是不能违反一些非空、惟1、类型不匹配约束。
例如我只想插入一条数据,而我只知道这我的的名字,因而我也能够插入一条记录,但只赋值 name 字段。
insert into person(id,name)
values (2,'cao');
复制代码
再次查询 person 表:
+----+------+------+-----------+--------------+
| id | name | age | phone | address |
+----+------+------+-----------+--------------+
| 1 | yang | 22 | 123232323 | 中国上海 |
| 2 | cao | NULL | NULL | NULL |
+----+------+------+-----------+--------------+
复制代码
关系型数据库中,全部未赋值的字段都默认为 NULL,固然这个默认值是能够修改的,你能够修改成空字符串或空格等等。
再说一个细节,当你想要插入一条数据时,而且但愿为该表的每个字段都赋值,那么你能够不用在表名后列举全部字段名,例如如下两条 insert 语句是等效的。
insert into person(id,name,age,phone,address)
values (1,'yang',22,'123232323','中国上海');
复制代码
insert into person
values (1,'yang',22,'123232323','中国上海');
复制代码
关于 insert,咱们暂时先说到这,后面介绍子查询的时候还会提到它,接着咱们来看修改数据 update。
二、修改数据
SQL UPDATE 语句用于修改表中现有的记录。基本格式以下:
UPDATE [table_name]
SET column1 = value1, column2 = value2...., columnN = valueN
复制代码
举个例子,这是 person 表如今的数据状况:
+----+------+------+-----------+--------------+
| id | name | age | phone | address |
+----+------+------+-----------+--------------+
| 1 | yang | 22 | 123232323 | 中国上海 |
| 2 | cao | NULL | NULL | NULL |
+----+------+------+-----------+--------------+
复制代码
咱们执行:
update person set address='浙江杭州';
复制代码
再来看 person 表:
+----+------+------+-----------+--------------+
| id | name | age | phone | address |
+----+------+------+-----------+--------------+
| 1 | yang | 22 | 123232323 | 浙江杭州 |
| 2 | cao | NULL | NULL | 浙江杭州 |
+----+------+------+-----------+--------------+
复制代码
你会发现 person 表的全部记录的 address 字段全都修改成「浙江杭州」。
因此,通常来讲,咱们的 update 语句都会结合 where 子句作一个数据筛选,只修改符合条件的记录的 address 字段值。
例如:
update person set address='浙江杭州' where id = 1;
复制代码
三、删除数据
咱们使用 DELETE 语句对标数据进行删除,基本格式语法以下:
DELETE FROM [table_name]
WHERE [condition];
复制代码
一样,不追加 where 子句作条件筛选会致使整张表的数据丢失。例如咱们删除 id 为 1 的那条数据记录。
delete from person where id = 1;
复制代码
SQL SELECT 语句用于从数据库的表中取回所需的数据,并以表的形式返回。返回的表被称做结果集。
基本的查询语法以下:
SELECT column1, column2, columnN FROM table_name;
复制代码
若是须要查询一条记录中的全部的字段,能够用符号「*」替代全体,例如:
SELECT * FROM person;
复制代码
可查询出 person 表全部的记录:
+----+-------+------+-----------+--------------+
| id | name | age | phone | address |
+----+-------+------+-----------+--------------+
| 1 | yang | 22 | 231232132 | 中国上海 |
| 2 | cao | NULL | NULL | 浙江杭州 |
| 3 | li | 23 | 34567894 | 江苏南京 |
| 4 | huang | 33 | 34567894 | 湖北武汉 |
| 5 | zhang | 30 | 4567890 | 中国北京 |
+----+-------+------+-----------+--------------+
复制代码
这是最基本的查询,没有之一,接下来咱们将一点点的增长复杂度,更熟练的掌握查询语句。
一、where 子句
where 子句又被称为条件子句,用于筛选查询出来的数据集,指定的条件语句中可使用基本的算术、关系和逻辑运算,例如:>,<,=,!=,&&,||。
举个例子吧,person 表如今有以下数据:
+----+-------+------+------------+--------------+
| id | name | age | phone | address |
+----+-------+------+------------+--------------+
| 1 | yang | 22 | 231232132 | 中国上海 |
| 2 | cao | NULL | NULL | 浙江杭州 |
| 3 | li | 23 | 34567894 | 江苏南京 |
| 4 | huang | 33 | 34567894 | 湖北武汉 |
| 5 | zhang | 30 | 4567890 | 中国北京 |
| 6 | yang | 24 | 2343435353 | 山东青岛 |
+----+-------+------+------------+--------------+
复制代码
咱们现须要查询出,名字叫「yang」,年龄为「22」的记录,该怎么写呢?
select * from person
where name='yang'&& age=22;
复制代码
仍是很简单的,虽然 where 子句很简单,但它倒是咱们 SQL 查询中最重要的一个关键字,基本上每一条 SQL 语句都离不开它。
在指定条件中,除了咱们以上说的可使用基本的逻辑算术运算符,子查询也是须要依赖 where 的,咱们后面继续说。
二、LIKE 子句
LIKE 子句,咱们通常用来作一些简单的搜索查询,或者说模糊匹配,表达式主要涉及到两个符号:
举几个例子吧,一样以咱们的 person 表数据为例。
查询全部的数据,找到其中 name 字段以字符「ang」结尾的数据记录集合:
select * from person
where name like '%ang';
复制代码
执行 SQL,返回结果:
+----+-------+------+------------+--------------+
| id | name | age | phone | address |
+----+-------+------+------------+--------------+
| 1 | yang | 22 | 231232132 | 中国上海 |
| 4 | huang | 33 | 34567894 | 湖北武汉 |
| 5 | zhang | 30 | 4567890 | 中国北京 |
| 6 | yang | 24 | 2343435353 | 山东青岛 |
+----+-------+------+------------+--------------+
复制代码
查询全部的数据,找到其中 name 字段以字符「ang」结尾,而且前面还有一个任意字符的数据记录集合:
select * from person
where name like '_ang';
复制代码
执行 SQL,返回结果:
+----+------+------+------------+--------------+
| id | name | age | phone | address |
+----+------+------+------------+--------------+
| 1 | yang | 22 | 231232132 | 中国上海 |
| 6 | yang | 24 | 2343435353 | 山东青岛 |
+----+------+------+------------+--------------+
复制代码
三、in 子句
in 关键字也是使用在 where 子句的条件表达式中,它限制的是一个集合,只要字段的值在集合中即符合条件,例如:
select * from person
where age in (22,30,23);
复制代码
这个 SQL 语句能够查询出来全部年龄是 22,30,23 的人数据记录。
你也可使用 not in 反向限制,例如:
select * from person
where age not in (22,30,23);
复制代码
这个 SQL 则能够查出全部年龄不是这三个值的数据记录信息。
四、ORDER BY 子句
ORDER BY 子句根据一列或者多列的值,按照升序或者降序排列数据。某些数据库就默认以升序排列查询结果。
基本的 SQL 语法为:
SELECT column
FROM table_name
[WHERE condition]
[ORDER BY column1, column2, .. columnN] [ASC | DESC];
复制代码
ASC 表示数据结果集按升序排序,DESC 表示数据结果集按降序排序。
通常来讲,咱们按某一列进行排序便可,固然,有时候一列排序并不能彻底解决问题,若是按多列排序,那么当遇到某一列值相同的时候,就会参照第二个列参数将这些重复列值得数据记录再一次排序。
举个例子:
咱们将 person 表中的数据参照 id 列,倒序排序:
select * from person
order by id desc;
复制代码
执行 SQL,查看结果:
+----+-------+------+------------+--------------+
| id | name | age | phone | address |
+----+-------+------+------------+--------------+
| 6 | yang | 24 | 2343435353 | 山东青岛 |
| 5 | zhang | 30 | 4567890 | 中国北京 |
| 4 | huang | 33 | 34567894 | 湖北武汉 |
| 3 | li | 23 | 34567894 | 江苏南京 |
| 2 | cao | NULL | NULL | 浙江杭州 |
| 1 | yang | 22 | 231232132 | 中国上海 |
+----+-------+------+------------+--------------+
复制代码
须要注意的是,对于数字类型的字段排序而言还相对容易理解些,对于非数字类型的排序,可能你不必定能看懂它为何这样排序。
其实每一个数据库都预约义了不少的排序规则,不少数据的实现都默认使用 utf8_general_ci 排序规则,固然,若是你很熟悉各类排序规则,你也能够在建立数据表的时候去主动指定使用哪一种排序规则,通常使用默认排序规则就行。
五、GROUP BY 子句
GROUP BY 子句用于将查询返回的结果集进行一个分组,并展现各个分组中排在第一个的记录,将分组中其他成员隐藏。
咱们为 person 表添加几条数据,用于演示:
+----+-------+------+------------+----------+
| id | name | age | phone | address |
+----+-------+------+------------+----------+
| 1 | yang | 22 | 231232132 | 中国上海 |
| 2 | cao | 30 | 456789 | 浙江杭州 |
| 3 | li | 23 | 34567894 | 江苏南京 |
| 4 | huang | 33 | 34567894 | 湖北武汉 |
| 5 | zhang | 30 | 4567890 | 中国北京 |
| 6 | yang | 24 | 2343435353 | 山东青岛 |
| 7 | cao | 44 | 12312312 | 河南郑州 |
| 8 | huang | 45 | 5677675 | 安徽合肥 |
| 9 | yang | 80 | 3343738 | 江苏南通 |
+----+-------+------+------------+----------+
复制代码
注意观察姓名列,有几组重复的姓名。
咱们按照姓名对结果集进行分组,SQL 以下:
select * from person
group by name;
复制代码
执行 SQL,获得结果:
+----+-------+------+-----------+----------+
| id | name | age | phone | address |
+----+-------+------+-----------+----------+
| 2 | cao | 30 | 456789 | 浙江杭州 |
| 4 | huang | 33 | 34567894 | 湖北武汉 |
| 3 | li | 23 | 34567894 | 江苏南京 |
| 1 | yang | 22 | 231232132 | 中国上海 |
| 5 | zhang | 30 | 4567890 | 中国北京 |
+----+-------+------+-----------+----------+
复制代码
你看,分组以后,只展现每一个分组下排序第一的记录,其他成员隐藏。
细心的同窗可能发现了,分组后的数据记录排序怎么乱了,怎么不是默认的 id 升序排列了?
对,若是你没有显式执行排序方式的话,将默认以你用于分组参照的那个字段进行排序。
固然,咱们是能够执行排序方式的,使用 order by 子句:
select * from person
group by name
order by id;
复制代码
效果是这样:
+----+-------+------+-----------+----------+
| id | name | age | phone | address |
+----+-------+------+-----------+----------+
| 1 | yang | 22 | 231232132 | 中国上海 |
| 2 | cao | 30 | 456789 | 浙江杭州 |
| 3 | li | 23 | 34567894 | 江苏南京 |
| 4 | huang | 33 | 34567894 | 湖北武汉 |
| 5 | zhang | 30 | 4567890 | 中国北京 |
+----+-------+------+-----------+----------+
复制代码
这就是分组,可能会有同窗疑问,这样的分组有什么意义,分组是分完了,给我返回每一个分组的第一行记录有什么用?
实际上是这样的,咱们之因此进行分组,就是为了统计和估量每一个分组下的指标状况,好比这组数据的平均年龄、最高薪水等等等等。
而当咱们只是 「select *」的时候,数据库根本不知道你要干什么,换句话说就是你并无对每个分组中的数据进行任何的分析统计,因而给你返回该分组的第一行数据。
你要记住的是,每一个分组只能出来一个数据行,究竟让什么样的数据出来取决于你。
好比咱们计算每一个分组下的平均年龄:
select avg(age) as '平均年龄' from person
group by name;
复制代码
查询结果:
+----------+
| 平均年龄 |
+----------+
| 37.0000 |
| 39.0000 |
| 23.0000 |
| 42.0000 |
| 30.0000 |
+----------+
复制代码
这里涉及了一个求平均数的函数 avg,咱们后续会介绍这些经常使用函数,这里你体会下其意思就行。
六、HAVING 子句
HAVING 子句在我看来就是一个高配版的 where 子句,不管是咱们的分组或是排序,都是基于以返回的结果集,也就是说 where 子句的筛选已经结束。
那么若是咱们对排序、分组后的数据集依然有筛选需求,就用到咱们的 HAVING 子句了。
例如:
select avg(age) as vage from person
group by name
having vage>23;
复制代码
分组以后,咱们获得每一个分组中数据的平均年龄,再者咱们经过 having 语句筛选出平均年龄大于 23 的数据记录。
以上咱们介绍了六个子句的应用场景及其使用语法,可是若是须要同时用到这些子句,语法格式是什么样的?做用优先级是什么样的?
SELECT column1, column2
FROM table
WHERE [ conditions ]
GROUP BY column1, column2
HAVING [ conditions ]
ORDER BY column1, column2
复制代码
你们必定要记住这个模板,各个子句在 SQL 语句中的位置,能够不出现,但不得越位,不然就会报语法错误。
首先是 from 语句,查出表的全部数据,接着是 select 取指定字段的数据列,而后是 where 进行条件筛选,获得一个结果集。
接着 group by 分组该结果集并获得分组后的数据集,having 再一次条件筛选,最后才轮到 order by 排序。
篇幅已经很长了,再也不继续了,有关子查询、链接查询以及一些细节咱们放在下一篇,本篇的重点是理解上述模板中的各个子句,并记住他们之间的做用优先级。