(My)SQL 使用入门---DML语句
2009-04-01 15:14
393 查看
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
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
相关文章推荐
- (My)SQL 使用入门---DDL语句
- asp经典入门教程 在ASP中使用SQL 语句第1/2页
- Mysql使用入门(一)sql语句分类
- NDatabase 入门,简单使用 增删改查。让NDatabase带你脱离ADO.net,各种SQL 语句,各种DBMS,各种CRM,IOC之类的烦恼。我们也不需要仓库设计模式了,你妹的。不要表了,不要设计数据库字段了。就这样!
- Mysql基础入门-SQL_DML语句
- 数据库SQL之DML语句的使用
- (My)SQL使用入门:
- asp经典入门教程 在ASP中使用SQL 语句第1/2页
- 数据库之Oracle的使用【入门版,包括常用的Sql语句】
- IT咨询顾问:一次吐血的项目救火 java或判断优化小技巧 asp.net core Session的测试使用心得 【.NET架构】BIM软件架构02:Web管控平台后台架构 NetCore入门篇:(十一)NetCore项目读取配置文件appsettings.json 使用LINQ生成Where的SQL语句 js_jquery_创建cookie有效期问题_时区问题
- (My)SQL 使用入门(详细)
- My Sql WorkBench基本使用 以及 基本sql语句
- 使用 EXPLAIN PLAN 获取SQL语句执行计划
- 关于SQL语句的使用心得
- 使用SQL语句还原数据库 2012.3.20
- oracle中使用SQL递归语句的例子
- mysql使用sql语句同步数据
- MySQL中明知道查询结果只有一个,SQL语句中使用LIMIT 1会提高查询效率
- C# 2010 从入门到精通 学习笔记4 第5章 使用复合赋值和循环语句
- 使用 gvim 处理sql语句