【无标题】

sql语句中的DQL语句

1 查询一个字段

select 字段名 from 表名

select 和 from 都是关键字

字段名和表名都是标识符

强调

对于所有SQl语句来说,是通用的,所有SQL语句都以“;”结尾,另外SQL语句不区分大小写

2 查询两个字段或者多个字段

select 字段名,字段名 from 表名

3 查询所有字段

  • 可以把每个字段都写上
  • 使用* : 这种方法的使用缺点,效率低,可读性差,在实际开发中不建议,自己玩没问题

4.条件查询

4.1 什么是条件查询

  • 不是将所有数据都查出来,二是查询符合条件的
  • 语法格式:
select
字段1,字段2,字段3
from
表名
where
条件;

5.分组查询

5.1 什么是分组查询

在实际的应用中,有可能有这样的需求,需要先进行分组,然后对每一组的数据进行操作,这个时候就需要分组查询

select。。。from。。。group by。。。

5.2 将之前的关键字组合在一起,看一下执行顺序

select …

where…

where…

group by…

order by…

以上关键词的执行顺序不能颠倒

  1. from
  2. where
  3. group by
  4. select
  5. order by

为什么分组函数不能直接使用在where后面?

分组函数在使用的时候必须先分组之后才能使用,where执行的时候,还没有分组,使用where后面不能出现分组函数

select sum(sal) from emp;

可以执行,因为select,在group by 之后执行。

4.2 条件查询语句

  • =(等号);<>(不等号)

  • between… and…,(>=,<=),使用between … and … 的时候,必须遵循左小右大的原则,而且between … and … 是闭区间,包括两端的值

  • 如果要查询值为null的表:要用is,在数据库中null不能使用等号来衡量,要用is null,数据库中的null表示啥也没有,不是一个值,所以不能用等号。

  • and 两个条件限制

  • or 查询两个条件符合的

select empty,ename from emp where job= ‘’ or job = ‘’

  • 如果and和or同时出现,那么and的优先级大于or的优先级,解决办法,在or的语句条件加上括号以后在开发中,如果不确定优先级就加小括号就行了
  • in 包含,相当于多个or ,not in表示不是这些条件的数据

select empno,ename,job from emp in(‘字段名’,‘字段名’)

  • like:模糊查询,支持%或者下划线匹配

% :表示匹配任意多个字符

_:表示任意一个字符

select empno,ename,job from emp like ‘%T’//表示找出以T结尾的数据

select empno,ename,job from emp like ‘K%’//表示找出以K开头的数据

select empno,ename,job from emp like ‘_T%’//表示找出第二个字母是T的

select empno,ename,job from emp like ‘__T%’//表示找出第三个字母是T的

  • 由于_在模糊查询中有特殊含义,所以假如我想找出名字中有下划线的,要加上转义字符“\”

6.连接查询

6.1 什么是链接查询

  • 从一张表中查询,成为单独查询
  • 跨表查询,多张表联合起来进行数据查询,就是连接查询

6.2 连接查询的分类

6.2.1根据年代分类

sql92;sql99(重点99)

6.2.2 根据表链接的方式分类

内连接,外连接

内连接:

  1. 等值连接
  2. 非等值连接
  3. 自连接

外连接:

  1. 左连接
  2. 有链接

全连接(no)

6.3 外连接查询

查询每个员工的部门

6.3.1 笛卡尔积现象

两张表链接没有任何条件限制:

select ename,dname from emp,dept;

mysql> select ename,dname from emp,dept;
+--------+------------+
| ename  | dname      |
+--------+------------+
| SMITH  | ACCOUNTING |
| SMITH  | RESEARCH   |
| SMITH  | SALES      |
| SMITH  | OPERATIONS |
| ALLEN  | ACCOUNTING |
| ALLEN  | RESEARCH   |
| ALLEN  | SALES      |
| ALLEN  | OPERATIONS |
| WARD   | ACCOUNTING |
| WARD   | RESEARCH   |
| WARD   | SALES      |
| WARD   | OPERATIONS |
| JONES  | ACCOUNTING |
| JONES  | RESEARCH   |
| JONES  | SALES      |
| JONES  | OPERATIONS |
| MARTIN | ACCOUNTING |
| MARTIN | RESEARCH   |
| MARTIN | SALES      |
| MARTIN | OPERATIONS |
| BLAKE  | ACCOUNTING |
| BLAKE  | RESEARCH   |
| BLAKE  | SALES      |
| BLAKE  | OPERATIONS |
| CLARK  | ACCOUNTING |
| CLARK  | RESEARCH   |
| CLARK  | SALES      |
| CLARK  | OPERATIONS |
| SCOTT  | ACCOUNTING |
| SCOTT  | RESEARCH   |
| SCOTT  | SALES      |
| SCOTT  | OPERATIONS |
| KING   | ACCOUNTING |
| KING   | RESEARCH   |
| KING   | SALES      |
| KING   | OPERATIONS |
| TURNER | ACCOUNTING |
| TURNER | RESEARCH   |
| TURNER | SALES      |
| TURNER | OPERATIONS |
| ADAMS  | ACCOUNTING |
| ADAMS  | RESEARCH   |
| ADAMS  | SALES      |
| ADAMS  | OPERATIONS |
| JAMES  | ACCOUNTING |
| JAMES  | RESEARCH   |
| JAMES  | SALES      |
| JAMES  | OPERATIONS |
| FORD   | ACCOUNTING |
| FORD   | RESEARCH   |
| FORD   | SALES      |
| FORD   | OPERATIONS |
| MILLER | ACCOUNTING |
| MILLER | RESEARCH   |
| MILLER | SALES      |
| MILLER | OPERATIONS |
+--------+------------+
56 rows in set (0.00 sec)

当两张表进行连接查询,没有任何条件限制的时候,最终查询结果条数,是两张表条数的乘积,这种现象被称为笛卡尔积现象(一个数学现象)

6.3.2 如何避免笛卡尔积现象

连接时,添加条件闲着;

select ename,dname from emp,dept where emp.deptno = dept.deptno;

mysql> select ename,dname from emp,dept where emp.deptno = dept.deptno;
+--------+------------+
| ename  | dname      |
+--------+------------+
| CLARK  | ACCOUNTING |
| KING   | ACCOUNTING |
| MILLER | ACCOUNTING |
| SMITH  | RESEARCH   |
| JONES  | RESEARCH   |
| SCOTT  | RESEARCH   |
| ADAMS  | RESEARCH   |
| FORD   | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| TURNER | SALES      |
| JAMES  | SALES      |
+--------+------------+
14 rows in set (0.00 sec)
  • 这样写避免了笛卡尔积现象,但是匹配次数没有减少,仍然是56次,只不过进行了四选一

select emp.ename,dept.dname from emp,dept where emp.deptno = dept.deptno;

给表起别名(这是92语法)

select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;

通过笛卡尔积现象得出,连接的表越多效率越低,尽量避免表的连接

6.3.3 内连接的等值连接

仍然是查询每个员工所在的部门名称

select e.ename,d.dname from emp e join dept d on e.deptno = d.deptno;

这是99语法

相较于92语法来说,99语法结构更清晰一点,

sql99的一个优点是:表连接的条件是独立的,连接之后,如果还想继续筛选,可以在后面继续添加where

select

e.ename,d.dname

from

emp e

inner join //inner是可以省略的,但是带上可以一言就看出来这是一个内连接(可读性更好)

dept d

on

e.deptno = d.deptno;//这个条件是一个等量关系,所以被称为等值连接

6.3.4 内连接的非等值连接

案例:找出每个员工的薪资等级,要求显示员工名,薪资,薪资等级

条件不是一个等量关系,称为非等值连接

select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;

mysql> select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;
+--------+---------+-------+
| ename  | sal     | grade |
+--------+---------+-------+
| SMITH  |  800.00 |     1 |
| ALLEN  | 1600.00 |     3 |
| WARD   | 1250.00 |     2 |
| JONES  | 2975.00 |     4 |
| MARTIN | 1250.00 |     2 |
| BLAKE  | 2850.00 |     4 |
| CLARK  | 2450.00 |     4 |
| SCOTT  | 3000.00 |     4 |
| KING   | 5000.00 |     5 |
| TURNER | 1500.00 |     3 |
| ADAMS  | 1100.00 |     1 |
| JAMES  |  950.00 |     1 |
| FORD   | 3000.00 |     4 |
| MILLER | 1300.00 |     2 |
+--------+---------+-------+
14 rows in set (0.00 sec)
6.3.5内连接的自连接

案例:查询每个员工的领到

技巧:吧一张表看做两张表

select a.ename as ‘员工名’ ,b.ename as ‘领导名’ from emp a join emp b on a.mgr = b.empno;

mysql> select a.ename as '员工名' ,b.ename as '领导名' from emp a join emp b on a.mgr = b.empno;
+--------+--------+
| 员工名  | 领导名  |
+--------+--------+
| SMITH  | FORD   |
| ALLEN  | BLAKE  |
| WARD   | BLAKE  |
| JONES  | KING   |
| MARTIN | BLAKE  |
| BLAKE  | KING   |
| CLARK  | KING   |
| SCOTT  | JONES  |
| TURNER | BLAKE  |
| ADAMS  | SCOTT  |
| JAMES  | BLAKE  |
| FORD   | JONES  |
| MILLER | CLARK  |
+--------+--------+
13 rows in set (0.00 sec)
  1. 3.6内连接的特点

    能够完全匹配上这个条件的数据查出来

6.4 外连接

如果有额外需求:比如包括没有匹配的也要查出来:

select e.ename,d.dname from emp e right join dept d on e.deptno = d.deptno;//这是一个右外连接,right代表:将join关键字右边的这张表看成主表,主要是为了将这张表的数据全部查询出来,捎带着关联查询左边的表

mysql> select   e.ename,d.dname   from   emp  e  right  join  dept  d    on   e.deptno = d.deptno;
+--------+------------+
| ename  | dname      |
+--------+------------+
| CLARK  | ACCOUNTING |
| KING   | ACCOUNTING |
| MILLER | ACCOUNTING |
| SMITH  | RESEARCH   |
| JONES  | RESEARCH   |
| SCOTT  | RESEARCH   |
| ADAMS  | RESEARCH   |
| FORD   | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| TURNER | SALES      |
| JAMES  | SALES      |
| NULL   | OPERATIONS |
+--------+------------+
15 rows in set (0.01 sec)

带有right的是右外连接,又叫做右连接,带有left的是左连接,任何一个右连接都有左连接的写法,任何一个左连接都有右连接的写法

外连接在join前面有一个outer,但是可以省略

外连接的查询结果条数一定>=内连接的查询结果

案例:查询每个员工的上级领导,要求显示所有的员工和领导名字

select a.empno,a.ename,b.ename from emp a left join emp b on a.mgr = b.empno;

mysql> select a.empno,a.ename,b.ename from emp a left join emp b on a.mgr = b.empno;
+-------+--------+-------+
| empno | ename  | ename |
+-------+--------+-------+
|  7369 | SMITH  | FORD  |
|  7499 | ALLEN  | BLAKE |
|  7521 | WARD   | BLAKE |
|  7566 | JONES  | KING  |
|  7654 | MARTIN | BLAKE |
|  7698 | BLAKE  | KING  |
|  7782 | CLARK  | KING  |
|  7788 | SCOTT  | JONES |
|  7839 | KING   | NULL  |
|  7844 | TURNER | BLAKE |
|  7876 | ADAMS  | SCOTT |
|  7900 | JAMES  | BLAKE |
|  7902 | FORD   | JONES |
|  7934 | MILLER | CLARK |
+-------+--------+-------+
14 rows in set (0.02 sec)

6.5 三张表或者四张表链接

语法:

select … from a join b on a和b的连接条件 join c on a和c的连接条件 join d on a和d的连接条件

案例:找出每个员工的部门名称以及工资等级,要求系那是员工名,部门名,薪资,薪资低等级

select e.ename,d.dname,e.sal,s.grade from emp e join dept d on e.deptno = d.deptno join salgrade s on e.sal between s.losal and s.hisal;

mysql> select  e.ename,d.dname,e.sal,s.grade  from  emp e join  dept  d  on  e.deptno = d.deptno  join salgrade  s  on  e.sal between s.losal and s.hisal;
+--------+------------+---------+-------+
| ename  | dname      | sal     | grade |
+--------+------------+---------+-------+
| SMITH  | RESEARCH   |  800.00 |     1 |
| ALLEN  | SALES      | 1600.00 |     3 |
| WARD   | SALES      | 1250.00 |     2 |
| JONES  | RESEARCH   | 2975.00 |     4 |
| MARTIN | SALES      | 1250.00 |     2 |
| BLAKE  | SALES      | 2850.00 |     4 |
| CLARK  | ACCOUNTING | 2450.00 |     4 |
| SCOTT  | RESEARCH   | 3000.00 |     4 |
| KING   | ACCOUNTING | 5000.00 |     5 |
| TURNER | SALES      | 1500.00 |     3 |
| ADAMS  | RESEARCH   | 1100.00 |     1 |
| JAMES  | SALES      |  950.00 |     1 |
| FORD   | RESEARCH   | 3000.00 |     4 |
| MILLER | ACCOUNTING | 1300.00 |     2 |
+--------+------------+---------+-------+
14 rows in set (0.01 sec)

案例:找出每个员工的部门名称以及工资等级,要求显示员工名,领导名,部门名,薪资,薪资等级

select e.ename,d.dname,e.sal,s.grade from emp e join dept d on e.deptno = d.deptno join salgrade s on e.sal between s.losal and s.hisal left join emp l on e.mgr = l.empno;

mysql> select  e.ename,d.dname,e.sal,s.grade  from  emp e join  dept  d  on  e.deptno = d.deptno  join salgrade  s  on  e.sal between s.losal and s.hisal  left  join  emp l on e.mgr = l.empno;
+--------+------------+---------+-------+
| ename  | dname      | sal     | grade |
+--------+------------+---------+-------+
| SMITH  | RESEARCH   |  800.00 |     1 |
| ALLEN  | SALES      | 1600.00 |     3 |
| WARD   | SALES      | 1250.00 |     2 |
| JONES  | RESEARCH   | 2975.00 |     4 |
| MARTIN | SALES      | 1250.00 |     2 |
| BLAKE  | SALES      | 2850.00 |     4 |
| CLARK  | ACCOUNTING | 2450.00 |     4 |
| SCOTT  | RESEARCH   | 3000.00 |     4 |
| KING   | ACCOUNTING | 5000.00 |     5 |
| TURNER | SALES      | 1500.00 |     3 |
| ADAMS  | RESEARCH   | 1100.00 |     1 |
| JAMES  | SALES      |  950.00 |     1 |
| FORD   | RESEARCH   | 3000.00 |     4 |
| MILLER | ACCOUNTING | 1300.00 |     2 |
+--------+------------+---------+-------+
14 rows in set (0.00 sec)

7.子查询

7.1 什么是子查询

select语句中嵌套select语句,被嵌套的select语句成为子查询

7.2 子查询都可以出现在哪里

select

…(select)

from

…(select)

where

…(select)

7.3 where语句中的子查询

案例:找出比最低工资高的员工的姓名和工资

select ename,sal from emp where sal > (select min(sal) from emp);

mysql> select  ename,sal from emp where sal > (select min(sal) from emp);
+--------+---------+
| ename  | sal     |
+--------+---------+
| ALLEN  | 1600.00 |
| WARD   | 1250.00 |
| JONES  | 2975.00 |
| MARTIN | 1250.00 |
| BLAKE  | 2850.00 |
| CLARK  | 2450.00 |
| SCOTT  | 3000.00 |
| KING   | 5000.00 |
| TURNER | 1500.00 |
| ADAMS  | 1100.00 |
| JAMES  |  950.00 |
| FORD   | 3000.00 |
| MILLER | 1300.00 |
+--------+---------+
13 rows in set (0.00 sec)

优先执行子查询

7.4 from语句下的子查询

注意:from后面的每个子查询又可以将子查询的结果当做一张临时表。(技巧)

案例:找出每个岗位的平均工资的薪资等级

select job,avg(sal) from emp group by job;

select t.*,s.grade from (select job,avg(sal) as avgsal from emp group by job) t join salgrade s on t.avgsal between s.losal and s.hisal;

mysql> select t.*,s.grade  from  (select  job,avg(sal)  as  avgsal from  emp  group  by  job)  t  join  salgrade  s  on  t.avgsal  between  s.losal  and s.hisal;
+-----------+-------------+-------+
| job       | avgsal      | grade |
+-----------+-------------+-------+
| CLERK     | 1037.500000 |     1 |
| SALESMAN  | 1400.000000 |     2 |
| ANALYST   | 3000.000000 |     4 |
| MANAGER   | 2758.333333 |     4 |
| PRESIDENT | 5000.000000 |     5 |
+-----------+-------------+-------+
5 rows in set (0.01 sec)

7.5 在select后面出现的子查询

select e.ename,(select d.dname from dept d where e.deptno = d.deptno) as dname from emp e;

mysql> select  e.ename,(select  d.dname  from  dept  d  where  e.deptno = d.deptno)  as dname  from  emp e;
+--------+------------+
| ename  | dname      |
+--------+------------+
| SMITH  | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| JONES  | RESEARCH   |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| CLARK  | ACCOUNTING |
| SCOTT  | RESEARCH   |
| KING   | ACCOUNTING |
| TURNER | SALES      |
| ADAMS  | RESEARCH   |
| JAMES  | SALES      |
| FORD   | RESEARCH   |
| MILLER | ACCOUNTING |
+--------+------------+
14 rows in set (0.00 sec)
  • 对于select后面的子查询只能一次返回一条结果,多余一条就报错

7.6union合并查询结果

案例:查询工作岗位是MANAGER和SALESMAN的员工

select ename,job from emp where job = ‘MANAGER’

union

select ename,job from emp where job = ‘SALESMAN’;

mysql> select  ename,job  from  emp  where  job = 'MANAGER'
    ->
    -> union
    ->
    -> select  ename,job  from  emp  where job = 'SALESMAN';
+--------+----------+
| ename  | job      |
+--------+----------+
| JONES  | MANAGER  |
| BLAKE  | MANAGER  |
| CLARK  | MANAGER  |
| ALLEN  | SALESMAN |
| WARD   | SALESMAN |
| MARTIN | SALESMAN |
| TURNER | SALESMAN |
+--------+----------+
7 rows in set (0.01 sec)

union的效率要高一些。对于表连接来说,每一次新表,则匹配的次数满足笛卡尔积爱,成倍的翻。。。但是union可以见识匹配次数,在减少匹配次数的情况了,号可以完成两个结果的拼接。

a 表连接 b 连接 c

  1. 使用表连接需要1000次
  2. 使用union a连接b a连接c 需要200次

union相当于是吧乘法变成了加法

7.7 union使用的注意事项

select ename,job from emp where job = ‘MANAGER’

union

select ename from emp where job = ‘SALESMAN’;

这样写会报错,union在合并的时候,要求两个结果列数相同

select ename,job from emp where job = ‘MANAGER’

union

select ename,sal from emp where job = ‘SALESMAN’;

这样写mysql可以,但是oracl会报错,合并时,数据类型也要相同

7.8 limit的使用

案例:按照薪资降序,取排在前5的员工

select

ename,sal

from

emp

order by

sal desc

limit 0,5;

mysql> select
    ->
    -> ename,sal
    ->
    -> from
    ->
    -> emp
    ->
    -> order by
    ->
    -> sal desc
    ->
    -> limit 5;
+-------+---------+
| ename | sal     |
+-------+---------+
| KING  | 5000.00 |
| SCOTT | 3000.00 |
| FORD  | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
+-------+---------+
5 rows in set (0.01 sec)
  • 完整用法:limit startIndex length//startIndex表示起始下标 length是长度
  • 缺省用法:limit length //默认下标从0开始

需要注意的是:limit在order by之后执行

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值