DML语句(数据操纵语言)

DML操作是只对数据库中表记录的操作,主要包括表记录的插入(insert)、更新(update)、删除(delete)和查询(select)。

1.插入记录:
1)INSERT INTO tablename (field1,field2,……fieldn) VALUES(value1,value2,……valuesn);
向表 emp 中插入以下记录:ename 为 zzx1,hiredate 为 2000-01-01,sal 为 2000,deptno为 1,
如图:insert into emp (ename,hiredate,sal,deptno) values('zzx1','2000-01-01','2000',1);


也可以不用指定字段名称,但是 values 后面的顺序应该和字段的排列顺序一致:
insert into emp values('lisa','2003-02-01','3000',2);
这里emp后面没有跟字段,所以values后面要写全或者写null。
后面跟了,则不用管,没有写得会自动赋默认值null。

举例:插入没有写全字段类型的数据,插入emp后面带类型的数据
如图:

2).一次插入多条记录:(节省网络开销,大大提高了插入效率)
INSERT INTO tablename (field1, field2,……fieldn)
VALUES
(record1_value1, record1_value2,……record1_valuesn),
(record2_value1, record2_value2,……record2_valuesn),
……
(recordn_value1, recordn_value2,……recordn_valuesn);
注:每条记录之间用逗号分隔。
举例:对表dept一次插入两条记录:
如图:insert into dept values(5,'dept5'),(6,'dept6');

2.更新记录:
1)UPDATE tablename SET field1=value1,field2.=value2,……fieldn=valuen [WHERE CONDITION]

例如:将表 emp 中 ename 为“lisa”的薪水(sal)从 3000 更改为 4000:
如图:update emp set sal=4000 where ename='lisa';


2)同时更新表 emp 中的字段 sal 和表 test1 中的字段 deptname:
如图:
update emp a,dept b set a.sal=a.sal*b.deptno,b.deptname=a.ename where a.deptno=b.deptno;

注意:多表更新的语法更过的用在了根据一个表的字段,来动态的更新另外一个表的字段。

3.删除记录:
1)DELETE FROM tablename [WHERE CONDITION]
例如:在emp中将ename为lisa的记录全部删除
如图:delete from emp where ename='lisa';

2)一次删除多个表:
DELETE t1,t2…tn FROM t1,t2…tn [WHERE CONDITION]
例如:将表 emp 和 test1 中 deptno 为 1 的记录同时都删除:
如图:

注意:不管是单表还是多表,不加 where 条件将会把表的所有记录删除,所以操作时一定要小心。

4.查询记录:
SELECT * FROM tablename [WHERE CONDITION]

查询不重复的记录:
有时需要将表中的记录去掉重复后显示出来,可以用distinct关键字来实现:

5.条件查询:
在很多情况下,用户并不需要查询所有的记录,而只是需要根据限定条件来查询一部分数据,用 where 关键字可以来实现这样的操作。
select * from emp where deptno=2;

6.排序和限制:
我们经常会有这样的需求,取出按照某个字段进行排序后的记录结果集,这就用到了数据库的排序操作,用关键字 ORDER BY 来实现,语法如下:
SELECT * FROM tablename [WHERE CONDITION] [ORDER BY field1 [DESC|ASC],field2 [DESC|ASC],……fieldn [DESC|ASC]]
注:DESC 和 ASC是排序顺序关键字,DESC表示按照字段进行降序排列,ASC表示升序排列,如果不写关键字默认是升序排列。ORDER BY 后面可以跟多个不同的排序字段,并且每个排序字段可以有不同的排序顺序。
例如:把emp表中的记录按照工资由高到低进行显示:


注:如果排序字段的值一样,则值相同的字段按照第二个排序字段进行排序,一次类推。如果只有一个排序字段,则这些字段相同的记录将会无序排列。

对于排序后的记录,如果只希望显示一部分,而不是全部,可以使用LIMIT关键字来实现,LIMIT语法如下;
SELECT ……[LIMIT offset_start,row_count];
其中offset_start表示记录的起始偏移量,row_count表示显示的行数。
在默认情况下,起始偏移量为0,只需要写记录行数就可以,这时候,显示的实际是前n条记录。
例如:
显示 emp 表中按照 sal 排序后的前 2 条记录:
select * from emp order by sal limit 2;

显示 emp 表中按照 sal 排序后从第二条记录开始,显示 2 条记录:
select * from emp order by sal limit 1,2;

注:limit经常和order by一起配合使用来进行记录的分页显示。
limit属于MySQL扩展SQL92后的语法,在其它数据库上并不能通用。

7.聚合:
很多时候,我们常常要做一些汇总的工作,如统计公司人数等等。这时就要用到SQL的聚合操作。
语法:
SELECT [field1,field2,……fieldn] fun_name
FROM tablename
[WHERE where_contition]
[GROUP BY field1,field2,……fieldn
[WITH ROLLUP]]
[HAVING where_contition]

fun_name表示要做的聚合操作,也就是聚合函数,常用的有sum(求和)、count(*)(记录数)、max(最大值)、min(最小值)
GROUP关键字表示要进行分类聚合的字段,比如要按照部门分类统计员工数量,部门就应该卸载group by后面。
WITH ROLLUP是可选语法,表明是否对分类聚合后的结果进行再汇总。
HAVING关键字表示对分类后的结果再进行条件的过滤。

注:
HAVING和WHERE的区别?
having是对聚合后的结果进行条件的过滤,而where是在聚合前就对记录进行过滤,如果逻辑允许,我们尽可能用where先过滤记录,这样因为结果集减少,将对聚合的效率大大提高,最后再根据逻辑看是否用having进行再过滤。

例如,要 emp 表中统计公司的总人数:
select count(1) from emp;

在此基础上,要统计各个部门的人数:
select deptno,count(1) from emp group by deptno;

既要统计各部门人数,又要统计总人数:
select deptno,count(1) from emp group by deptno with rollup;

统计人数大于 1 人的部门:
select deptno,count(1) from emp group by deptno having count(1)>1;

最后统计公司所有员工的薪水总额、最高和最低薪水:
select * from emp;

8.表连接
当需要同时显示多个表的字段时,就可以用表连接来实现这样的功能。
从大类上分,表连接分为内连接和外连接,
它们之间的最主要区别是
内连接仅选出两张表中互相匹配的记录。(常用)
外连接会选出其它不匹配的记录。

例如:查询出所有雇员的名字和所在部门名称,因为雇员名称和部门分别存放在表 emp 和dept 中,因此,需要使用表连接来进行查询:

外连接分为左连接和右连接:
左连接:包含所有的左边表中的记录甚至是右边表的记录中没有和它匹配的记录。
右连接:包含所有的右边表中的记录甚至是左边表中没有和它匹配的记录。

例如:查询 emp 中所有用户名和所在部门名称:

注:比较上述两个例子,两者本质的区别在于列出了所有的用户名,即使有的用户名并不存在合法的部门的名称。

左连接和右连接类似,两者之间可以相互转换。
例如:上述的例子改写成右连接:

9.子查询:
某些情况下,当我们查询的时候,需要的条件是另外一个select语句的结果,这个时候,就要用到子查询。用于子查询的关键字主要包括in、not in、=、!=、exists、not exists等。

例如:从emp表中查询出所有部门在 dept 表中的所有记录:

如果子查询记录数唯一,还可以用=代替in:

某些情况下,子查询可以转化为表连接
例如:

转换为表后:

注意:
1.MySQL以前的版本不支持子查询,需要用表连接来实现子查询的功能。
2.表连接在很多情况下用于优化子查询

10.记录联合:
我们经常会碰到这样的应用,将两个表的数据按照一定的查询条件查询出来后,将结果合并到一起显示出来,这个时候,就需要用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,去除重复记录后的结果。
来看下面例子,将emp和dept表中的部门编号的集合显示出来:

如果希望将结果去掉重复记录后显示:

原文地址:https://www.cnblogs.com/y3010179969/p/6357728.html