(My)SQL 使用入门---DML语句

    DML操作是指对数据库中表记录的操作,主要包括表记录的插入(insert)、更新(update)、删除(delete)和查询(select),是开发人员日常使用最频繁的操作。

 

1.

插入记录

INSERT INTO tablename(field1,dield2,……fieldn) VALUES (value1,value2,……valuesn);

 

例:向表emp中插入以下记录:ename为zzx1,hiredate为2000-01-01,sal为2000,deptno为1.

 

mysql>insert into emp (ename,hiredate,sal,depton) values ('zzx1','2000-01-01','2000',1);

 

也可以不用指定字段,但是values后面的,顺序要和字段的排列一致:

 

mysql> insert into emp ('lisa','2003-02-01','3000',2);

 

 含可空字段、非空但是含有默认的字段、自增字段,可以不用在insert后的字段列表里面出现,values后面只写对应字段的value。这些没写的字段可以自动设置为NULL、默认值,自增的下一个数字。

 

例:只对表中的ename和sal字段显式插入值:

mysql> insert into emp (ename,sal) values('dony',1000);

 

用INSERT语句一次插入多条记录:

INSERT INTO tablesname(field1,field2,……fieldn)

VALUES

(record1_value1,record1_value2,……record1_valuesn),

(record2_value2,record2_value2,……record2_valuesn),

……

(recordn_value1,recordn_value2,……recordn_valuesn)

;

 

例:对表dept一次插入两条记录:

mysql> insert into dept values (5,'dept5'),(6,'dept6');

 

 

 

 

 

2

更新记录(使用UPDATE关键字):

UPDATE tablename SET field1=value1,field2=value2,……fieldn=valuen [WHERE CONDITION];

例:将表emp中ename为"lisa"的薪水(sal)从3000更改4000。

mysql> update emp set=4000 where ename="lisa";

 

UPDATE命令可以同时更新多个表中数据:

UPDATE t1,t2…tn set t1.field1=expr1,tn.fieldn=exprn [WHERE CONDITION];

 

例:同时更新表emp中的字段sal和表dept中的字段deptname:

mysql> update emp a,dept b set a.sal=a.sal*b.deptno,b.deptname=a.ename where=a.deptno=b.deptno;

-----------------------------------------------------------------------

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

         的更新另外一个表的字段。

------------------------------------------------------------------------

 

3.

删除记录:

用delete命令删除不再需要的记录:

DELETE FROM tablename [WHERE CONDITION]

例:在emp中将ename为‘dony’的记录全部删除。

 

mysql> delete from emp where ename='dony';

 

MySQL中一次可以删除多个表的数据:

DELETE t1,t2……tn FROM t1,t2……tn [WHERE CONDITION]

4.

查询记录:

查询某个表中的全部记录:

SELECT * FROM tablename [WHERE CONDITION]

 

 其中“*”表示要将所有的记录都选出来,也可以用逗号分割的所有字段来代替。

 

(1)查询不重复的记录

有时需要将表中的记录去掉重复后显示出来

可以用distinct关键字来实现:

SELECT distinct col_name FROM tablename;

 

(2)条件查询(WHERE关键字)

例:查询所有deptn为1的记录。

mysql> select * from emp where deptnno=1;

 

where后面的条件是一个字段的=比较,除了=外,还可以使用>,<,>=,<=,!=等比较运算符

多个条件还可以使用or,and等逻辑进行多条件联合查询。

例: mysql> select * from emp where deptno=1 and sal<3000;

 

(3)排序(ORDER BY 关键字)和限制

 

排序:SELECT * FROM tablename [WHERE CONDITION] [ORDER BY field1 [DESC |ASC],field2 [DESC |ASC],……fieldn [DESC |ASC]]

 

 限制:SELECT ……[LIMIT offset_start,row_count]

        offset_start,表示记录的起始偏移量

        row_count,表示显示的行数

         默认时,起始偏移量为0,只需写记录行数就可以了,此时实际就是前民N条记录。

 

例:显示emp表中按照sal排序后的前3条记录:

mysql>select * from emp order by sal limit 3;

 

 

      显示emp表中按照sal排序后从第二条记录开始,显示3条记录:

mysql>select * from emp order by sal limit 1,3;

-------------------------------------------------------------------

注意:limit属于MySQL扩展SQL92后的语法,在其他数据库上并不

          能通用。

-------------------------------------------------------------------

 

 (4)聚合

 一般用于数据的汇总,用于统计数据等。

SELECT [field1,field2,……fieldn] fun_name

FROM tablename

[WHERE where_contition]

[Group BY field1,field2,……fieldn]

[WITH ROLLUP]

[HAVING where_contition]

-----------------------------------------------

参数说明:

1。fun_name 表示要做的聚合操作,即聚合函数

     常用的有sum(求和)、count(*)(记录数)、max(最大值)、min(最小值)。

2。GROUP BY 关键字表示要进行分类聚合的字段。如要按部门分类统计员工

      数量,部门就应该写再GROUP BY 后面。

3。WITH ROLLUP是可选语法,表明是否对分类聚合后的结果进行再汇总

4。HAVING 关键字表示对分类后的结果再进行条件的过滤

 

注意:

  having和where的区别在于having是对聚合后的结果进行条件的过滤,

  而where是在聚合前就对记录进行过滤,如果逻辑允许,我们尽可能用

  where先过滤记录,这样因为结果集减小,将对聚合的效率大大提高,

  最后再根据逻辑看是否用having进行再过滤。

 

------------------------------------------------

例:要emp表中统计公司的总人数:

mysql>select count(1) from emp;

+--------------+

|    count(1)    |

+--------------+

|           4        |

+--------------+  

1 row in set (0.00 sec)

 

 

在此基础上,要统计各个部门的人数:

mysql> select deptno,count(1) from emp group by deptno;

+---------+------------+

| deptno  | count(1)    |

+---------+------------+

|      1      |         2      |

|      2      |         1      |

|      4      |         1      |

+---------+------------+

 

3 row in set (0.00 sec)

 

更细一些,既要统计各部门的人数,又要统计总人数

 

mysql> select deptno,count(1) from emp group  by deptno with rollup;

+---------+------------+

| deptno  | count(1)    |

+---------+------------+

|      1      |         2      |

|      2      |         1      |

|      4      |         1      |

|    NULL  |         4      |

+---------+------------+

4 rows in set (0.00 sec)

 

统计人数大于1个的部门

 

mysql> select deptno,count(1) from emp group by deptno having count(1)>1;

+---------+------------+

| deptno  | count(1)    |

+---------+------------+

|      1      |         2      |

+---------+------------+

1 row in set (0.00 sec)

 

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

mysql> select * from emp;

+-----------+-------------+----------+-----------+

|  ename    | hiredate     |   sal       |  deptno    |

 

+-----------+-------------+----------+-----------+

|    zzx       |2000-01-01 | 100.00    |         1     |

|    lisa       |2003-02-01 | 400.00    |         2     |

|    bjguan  |2004-04-02 | 100.00    |         1     |

|    dony     |2005-02-05 | 2000.00  |         4     |

+-----------+-------------+----------+-----------+

4 rows in set (0.00 sec)

 

mysql>select sum(sal),max(sal),min(sal) from emp;

+-----------+-------------+----------+

| sum(sal)  | max(sal)    | min(sal)  | 

 +-----------+-------------+----------+

|  2600.00  |  2000.00     | 100.00    |

+-----------+-------------+-----------+

1 row in set (0.00 sec)

 

(5)表连接

  当需要同时显示多个表中的字段时,就可以用表连接来实现这样的功能

  从大类一分,表连接分为内连接和外连接,其最主要区别是:

  内连接仅选出两张表中互相匹配的记录

  外连接会选出其他不匹配的记录。我们常用内连接。

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

mysql> select * from emp;

+--------+------------+---------+--------+

| ename  | hiredate   | sal     | deptno |

+--------+------------+---------+--------+

| zzx    | 2000-01-01 | 2000.00 |      1 |

| lisa   | 2003-02-01 | 4000.00 |      2 |

| bjguan | 2004-04-02 | 5000.00 |      1 |

| bzshen | 2005-02-05 | 3000.00 |      3 |

+--------+------------+---------+--------+

4 rows in set

 

mysql> select * from dept;

+--------+----------+

| deptno | deptname |

+--------+----------+

|      1 | tech     |

|      2 | sale     |

|      3 | hr       |

+--------+----------+

3 rows in set

 

mysql> select ename,deptname from emp,dept where emp.deptno=dept.deptno;

+--------+----------+

| ename  | deptname |

+--------+----------+

| zzx    | tech     |

| lisa   | sale     |

| bjguan | tech     |

| bzshen | hr       |

+--------+----------+

4 rows in set

 

 

外连接又分为左连接和右连接

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

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

 

例,查询emp中所有用户名和所在部门名称(左连接)

mysql> select * from emp;

+--------+------------+---------+--------+

| ename  | hiredate   | sal     | deptno |

+--------+------------+---------+--------+

| zzx    | 2000-01-01 | 2000.00 |      1 |

| lisa   | 2003-02-01 | 4000.00 |      2 |

| bjguan | 2004-04-02 | 5000.00 |      1 |

| bzshen | 2005-02-05 | 3000.00 |      3 |

| dony   | 2005-04-01 | 4000.00 |      4 |

+--------+------------+---------+--------+

5 rows in set

 

mysql> select * from dept

;

+--------+----------+

| deptno | deptname |

+--------+----------+

|      1 | tech     |

|      2 | sale     |

|      3 | hr       |

+--------+----------+

3 rows in set

mysql> select ename,deptname from emp left join dept on emp.deptno=dept.deptno;

+--------+----------+

| ename  | deptname |

+--------+----------+

| zzx    | tech     |

| lisa   | sale     |

| bjguan | tech     |

| bzshen | hr       |

| dony   | NULL     |

+--------+----------+

5 rows in set

 

比较这个查询和上例中和查询,都是查询用户和部门名

两者的区别在于本例出了所有和用户名,即使有的用户名(dony)并不存在合法的法的部门名称(部门号为4,在deptno中没有这个部门);而上例中仅仅列出了存在合法部门的用户名和部门名称。

 

右连接和左连接类似,两者之间可以互相转化,例,上面的例子可以改写为如下的右连接:

mysql> select ename,deptname from dept right join emp on dept.deptno=emp.deptno;

+--------+----------+

| ename  | deptname |

+--------+----------+

| zzx    | tech     |

| lisa   | sale     |

| bjguan | tech     |

| bzshen | hr       |

| dony   | NULL     |

+--------+----------+

5 rows in set

(6)子查询

某些情况下,当进行查询时候,需要的条件是另外一个select语句的结果,此时就要用到子查询

用于子查询的关键字主要包括in, not in , =, != ,exists, not exists 等。

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

mysql> select * from emp;

+--------+------------+---------+--------+

| ename  | hiredate   | sal     | deptno |

+--------+------------+---------+--------+

| zzx    | 2000-01-01 | 2000.00 |      1 |

| lisa   | 2003-02-01 | 4000.00 |      2 |

| bjguan | 2004-04-02 | 5000.00 |      1 |

| bzshen | 2005-04-01 | 4000.00 |      3 |

| dony   | 2005-02-05 | 2000.00 |      4 |

+--------+------------+---------+--------+

5 rows in set

 

mysql> select * from dept;

+--------+----------+

| deptno | deptname |

+--------+----------+

|      1 | tech     |

|      2 | sale     |

|      3 | hr       |

|      5 | fin      |

+--------+----------+

4 rows in set

 

mysql> select * from emp where deptno in(select deptno from dept);

+--------+------------+---------+--------+

| ename  | hiredate   |  sal    | deptno |

+--------+------------+---------+--------+

| zzx    | 2000-01-01 | 2000.00 |      1 |

| lisa   | 2003-02-01 | 4000.00 |      2 |

| bjguan | 2004-04-02 | 5000.00 |      1 |

| bzshen | 2005-04-01 | 4000.00 |      3 |

+--------+------------+---------+--------+

4 rows in set

 

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

mysql>select * from emp where deptno=(select deptno from dept);

ERROR 1242(21000):Subquery return more than 1 row

mysql>select * from emp where deptno=(select deptno from dept limit 1);

+--------+------------+---------+--------+

| ename  | hiredate   |  sal    | deptno |

+--------+------------+---------+--------+

| zzx    | 2000-01-01 | 2000.00 |      1 |

| bjguan | 2004-04-02 | 5000.00 |      1 |

+--------+------------+---------+--------+

2 rows in set

 

mysql> select * from emp where deptno in(select deptno from dept);

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

+--------+------------+---------+--------+

| ename  | hiredate   |  sal    | deptno |

+--------+------------+---------+--------+

| zzx    | 2000-01-01 | 2000.00 |      1 |

| lisa   | 2003-02-01 | 4000.00 |      2 |

| bjguan | 2004-04-02 | 5000.00 |      1 |

| bzshen | 2005-04-01 | 4000.00 |      3 |

+--------+------------+---------+--------+

4 rows in set

转换为表连接后:

mysql>select emp .* from emp,dept where emp.deptno=dept.deptno;

+--------+------------+---------+--------+

| ename  | hiredate   |  sal    | deptno |

+--------+------------+---------+--------+

| zzx    | 2000-01-01 | 2000.00 |      1 |

| lisa   | 2003-02-01 | 4000.00 |      2 |

| bjguan | 2004-04-02 | 5000.00 |      1 |

| bzshen | 2005-04-01 | 4000.00 |      3 |

+--------+------------+---------+--------+

4 rows in set

将结果合并到一起显示出来,这个时候,就需要用UNION和UNION ALL关键字来实现这样的功能:

SELECT * FROM t1

UNION|UINON ALL

SELECT *FROM t2

……

(7)我们经常会碰到这样的应用,将两个表的数据按照一定的查询条件查询出来后,

UNION|UINON ALL

SELECT * FROM tn;

UNION和UINON ALL的主要区别是UINON ALL是把结果集直接合并在一起

而UNION是将UINON ALL 后的结果进行一次DISTINCT,去除了重复记录后和结果。

例:将emp和dept表中和部门编号的集合显示出来:

mysql> select * from emp;select * from dept;

+--------+------------+---------+--------+

| ename  | hiredate   | sal     | deptno |

+--------+------------+---------+--------+

| zzx    | 2000-01-01 | 100.00  |      1 |

| lisa   | 2003-02-01 | 400.00  |      2 |

| bjguan | 2004-04-02 | 100.00  |      1 |

| dony   | 2005-02-05 | 2000.00 |      4 |

+--------+------------+---------+--------+

4 rows in set

 

+--------+----------+

| deptno | deptname |

+--------+----------+

|      1 | tech     |

|      2 | sale     |

|      5 | fin      |

+--------+----------+

3 rows in set

 

mysql> select deptno from emp

    -> union all

    -> select deptno from dept;

+--------+

| deptno |

+--------+

|      1 |

|      2 |

|      1 |

|      4 |

|      1 |

|      2 |

|      5 |

+--------+

7 rows in set

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

mysql> select deptno from emp

    -> union

    -> select deptno from dept;

+--------+

| deptno |

+--------+

|      1 |

|      2 |

|      4 |

|      5 |

+--------+

4 rows in set

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值