之前已经介绍过SQL基础之DDL(数据库定义语言)语句,http://www.cnblogs.com/cxq0017/p/6433938.html(这是地址)
这篇文章主要介绍DML语句(数据库操纵语句)
DML语句
DML操作是指对数据库中表记录的操作,主要包括表记录的插入(insert)、更新(update)、删除(delete)和查询(select),是开发人员日常使用最频繁的操作.
1:插入记录
表创建好后,就可以往里面插入记录了,插入记录的基本语法如下:
INSERT INTO tablename(field1,field2,.....fieldn)VALUES(value1,value2,....,valuen);
例如向表employee中插入以下记录:ename 为Jason,edate 为2017-02-23,sal为20000,deptno为1,命令执行如下:
也可以不用指定字段名称,但是values后面的顺序应该和字段的排列顺序一致:
含可空字段,非空但是含有默认值的字段、自增字段,可以不用在insert后的字段列表里面出现,values后面只写对应字段名称的value,这些没写的字段可以自动设置为NULL,默认值、自增的下一个数字,这样在某些情况下可以大大缩短SQL语句的复杂性。
例如,只对表中的ename和sal字段显示插入值:
看实际插入值,果然为可空的两个字段都显示为NULL,在MySQL中,insert语句还有一个很好的特性,可以一次性插入多条记录,语法如下:
可以看出,每条记录之间都用逗号进行了分隔,下面的例子中,对表employee一次插入两条记录:
这个特性可以使得MySQL在插入大量记录时,节省很多的网络开销,大大提高插入效率
2:更新记录
表里的记录值可以通过update命令进行更改,语法如下:
UPDATE tablename SET field1=value1,field2=value2,.....fieldn=valuen[WHERE CONDITION]
现在将表中ename = ‘dony’的薪水sal 修改为19000。
在MySQL中,update命令可以同时更新多个表中数据,语法如下:
UPDATE t1,t2,.....tn set t1.field1 = expr1,tn.fieldn = exprn [WHERE CONDITION]
在下例中,同时更新表employee中的字段sal和表dept中字段的deptname;
至此,两个表的数据同时进行了更新。
注意:多表更新的语法更多了用在了根据一个表的字段来动态地更新另外一个表的字段。
3:删除记录
如果记录不再需要,可以用delete命令进行删除,语法如下:
DELETE FROM tablename [WHERE CONDITION]
例如,在employee中将ename为“dony”的记录全部删除,命令如下:
在MySQL中可以一次删除多个表的数据,语法如下:
DELETE t1,t2,.....tn FROM t1,t2,...tn [WHERE CONDITION]
如果from后面的表名用别名,则delete后面也要用相应的别名,否则会提示错误,
在下例中,同时删除表employee和dept中deptno为2的记录.
注意:不管是单表还是多表,不加where条件将会把表的所有记录删除,所以操作的时候一定要小心。
4:查询记录
数据插入到数据库中后,就可以使用SELECT命令进行各种各样的查询,使得输出的结果符合用户的要求,SELECT的语法和复杂,这里也就介绍最基本的语法。
SELECT * from tablename [WHERE CONDITION]
查询最简单的方式就是将记录全部选出,在下面的例子中,将employee的记录全部查询出来。
其中“*”表示要将所有的记录都选出来,也可以用逗号分割的所有字段来代替,例如以下两个查询是等价的。
select * from employee;
select ename,age,birthday,edate,sal,deptno from employee;
"*"好处的是当需要查询所有字段信息时,查询语句很简单,但是只查询部分字段的时候,必须要将字段一个一个列出来。
上例上已经介绍了查询全部记录的语法,但是实际应用中,用户还会遇到各种各样的查询要求,下面将分别介绍。
(1)查询不重复的记录。
有时需要将表中的记录去掉重复后显示出来,可以用distinct关键字来实现。
(2)条件查询
在很多情况下,用户并不需要查询所有的记录,而只是需要根据限定条件来查询一部分数据,用where关键字可以实现这样的操作。
例如,需要查询所有deptno为1的记录:
结果集中将符合条件的记录列出来了,上面的例子中,where后面的条件是一个字段的=比较,除了=外,还可以使用>,<,>=,<=,!=等比较运算符;多个条件之间还可以使用or、and等逻辑运算符进行多条件联合查询,运算符会在以后讲解。
以下是一个使用多字段条件查询的例子:
(3)排序和限制
我们经常会有这样的需求,取出按照某个字段进行排序后的记录结果集,这就用到了数据库的排序操作,用关键字ORDER BY来实现,语法如下:
SELECT * FROM tablename [WHERE CONDITION] [ORDER BY field1 DESC|ASC],field2[DESC|ASC],....fieldn[DESC|ASC];
其中,DESC和ASC是排列顺序关键字,DESC表示按照字段进行排序排列,ASC则表示升序排列,如果不写此关键字默认是升序排列,ORDER BY后面可以跟多个不同的排序字段,并且每个排序字段可以有不同的排序顺序。
例如,如果把employee表中的记录按照工资高低来进行显示;
如果排序字段的值一样,则值相同的字段按照第二个排序字段进行排序,依次类推,如果只有一个排序字段,则这些字段相同的记录将会无序排列。
对于排序后的记录,如果希望只显示一部分,而不是全部,这时,就可以使用LIMIT关键字来实现,LIMIT的语法如下:
SELECT ......[LIMIT offset_start,row_count];
其中,offset_start表示记录的起始偏移量,row_count表示显示的行数。
在默认情况下,起始偏移量是0,只需要写记录行数就可以了,这时,实际显示的就是前n条记录,例如,显示employee表中按照sal排序后的前2条记录。
如果要显示employee表中按照sal排序后从第二条记录开始的2条记录,可以使用以下命令:
limit经常喝order by一起配合使用来进行记录的分页显示。
注意:limit属于MySQL扩展SQL92后的语法,在其它数据库上并不能通用。
(4):聚合
很多情况下,用户都需要进行一些汇总操作,比如统计整个公司的人数或者统计每个部门的人数,这时就需要用到SQL的聚合操作。
聚合操作的语法如下:
SELECT [field1,field2,....fieldn] fun_name FROM tablename [WHERE where_condition] [GROUP BY field1,field2,...fieldn]
[WITH ROLLUP] [HAVING where_condition]
对其参数进行以下说明。
fun_name:表示要做的聚合操作,也就是聚合函数,常用的有sum()、count(*)、max()、min()。
GROUP BY:表示要进行分类聚合的字段,比如要按照部门分类统计员工数量,部门就应该写在group by后面。
WITH ROLLUP:是可选语法,表示是否对分类聚合后的结果进行再汇总。
HAVING:表示对分类后的结果再进行条件的过滤。
注意:having和where的区别在于,having是对聚合后的结果进行条件的过滤,而where是在聚合前就对记录进行过滤,如果逻辑允许,我们尽可能用where先过滤,这样因为结果集减小,将对聚合的效率大大提高,最后再根据逻辑看是否用having进行再过滤。
例如,要在employee表中统计公司的总人数
在此基础上,要统计各个部门的人数
更细一些。既要统计各部门的人数,又要统计总人数
统计人数大于1人的部门
最后统计公司所有员工的薪水总额,最高和最低薪水
(5)表连接
当需要同时显示多个表中的字段时,就可以用表连接来实现这样的功能,从大类上分,表连接分为内连接和外连接,它们之间的最主要区别是,内连接仅选出两张表中互相匹配的记录,而外连接会选出其它不匹配的记录,我们最常用的是内记录。
例如,查询出所有雇员的名字和所在部门名称,因为雇员名称和部门分别存在表employee和dept中,因此,需要使用表连接来进行查询。
外连接又分为左连接和右连接,具体定义如下.
.左连接:包含所有的左边表中的记录甚至是右边表中没有和它匹配的记录。
.右连接:包含所有的右边表中的记录甚至是左边表中没有和它匹配的记录。
例如,查询employee中所有用户名和所在部门名称:
比较这个查询和上例中的查询,都是查询用户名和部门名,两者的区别在于本例中列出了所有的用户名,即使有的用户名(lily)并不存在合法的部门名称(部门号为3,在dept中没有这个部门);而上例仅仅列出了存在合法部门的用户名和部门名称。
右连接和左连接类似,两者之间可以相互转化,例如,上面的例子可以改写为如下的右连接:
(6)子查询
某些情况之下,当进行查询的时候,需要的条件是从另外一个select语句的结果,这个时候就要用到子查询,用于子查询的关键字主要包括in、not in、=、!=、exists、not exists等。
例如,从employee表中查询出所有部门在dept表中的所有记录。
如果子查询记录数唯一,还可以用=代替in;
某些情况下,子查询可以转化为表连接。例如
注意:子查询和表连接之间的转换主要应用在两个方面。
.MySQL4.1以前的版本不支持子查询,需要用表连接来实现子查询的功能。
.表连接在很多情况下用于优化子查询.
(7)记录联合
我们经常会碰到这样的应用,将两个表的数据按照一定的查询条件查询出来后,将结果合并到一起显示出来,这个时候,就需要用union和union all关键字来实现这样的功能,具体语法如下:
SELECT * from t1
UNION|UNION ALL
SELECT * from t2
...
UNION|UNION ALL
SELECT*FROM tn;
UNION 和UNION ALL 的主要区别是UNION ALL 是把所有结果集直接合并在一起,而UNION 是将UNION ALL后的结果进行一次DISTINCT,去除重复记录后的结果;
看下面的例子,将employee和dept表中的部门编号的集合显示出来;
将结果去掉重复记录后显示如下:
本篇数据库操纵语句(DML)就结束了。会在下一篇文章讲到DCL(数据库控制语句)。