sql语法详解--DQL语句

2021/5/9 19:27:33

本文主要是介绍sql语法详解--DQL语句,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一,sql的学习心得

sql语言主要是对数据库进行操作,开发过程离不开对数据的增删改查,因此sql语言十分重要。
关于sql的学习主要是小白比较陌生,首先应该了解大致语法,然后去做一定量的联系,最后可以回过来系统的整理语法,易错点。
sql语句是很明确的,有很强的逻辑性,使用的方式也非常灵活。刚开始练习的时候可以把查表的要求写下来,然后进行分解,可以先完成
其中的一个要求,然后再把sql语句进行整合。同样一个问题可以有不同的sql语法来实现,可以多进行尝试。
推荐哔哩哔哩北京动力节点老杜的MySQL学习,视频也配有相应的练习题同时也提供下载非常方便。

二,sql语法详解

(一)简单语句的查询--DQL

1,基本语法

1.基本语法:
select 
  字段名1,字段名2 …… 
from 
  表名 ;
*注意:1:sql字段不区分大小写,但是建议大写,可以提高执行效率;
      2:任何一条sql语句以“;”结尾。

2.查询结果的列重命名(显示出来的结果以命名后的列名显示)

  例子1:select ename, sal*12 as yearSal from emp;
  例子2:select ename ,sal*12 as '年薪' from emp;
  说明:1,使用as关键字,关键字可以省略
       2,可以使用中文,但是要用英文双引号或单引号包裹,推荐单引号
       3,字段可以直接进行算术运算
3.查询结果排序

例子1:select ename,sal*12 from emp order by sal;
例子2:select ename,sal*12 from emp order by sal desc;
例子3:select ename,sal*12 from emp order by sal desc,ename asc;

说明:1,排序使用关键字 order by
      2,默认升序排列(由小到大)
      3,升序关键字在后面加 asc,降序使用 desc;
      4,可以对多字段联合排序,例子3就是工资相同时按名字字母的升序排列

2,条件查询

运算符 说明
= 等于
<>或!= 不等于
< 小于
<= 小于等于
> 大于
>= 大于等于
between... and ... 两个值之间,等同于>= and <==
is null 为null值(is not null不为空)
and 并且,交集
or 或者,并集
in 包含,相当于多个or(not in不在这个范围中)
not 可以取非,主要在is或in中使用
like 模糊查询,支持%或下划线匹配%匹配任意字符,下划线匹配单个字符
##语法格式##
  select
    字段名1,字段名2……
  from
    表名
  where
    判断条件;

1:between……and……
'例子1':select ename,sal from emp where sal >= 1100 and sal <= 3000;
'例子2':select ename,sal from emp where sal between 1100 and 3000;
'例子3':select ename,sal from emp where sal between 3000 and 1100; 
'例子4':select ename from emp where ename between 'A' and 'C';
说明:
  1,例子1和2是等价的,between...and...是闭区间[1000,3000];
  2,例子3没有结果,,,,,,,,,,,,,,因为between后面的数字一定要小于and后面的数字;
  3,例子4可以查询出来,单个字符也是对应的有数字。

2,null--空值的理解
'例子1':select ename,sal,comm from emp where comm is null;
说明:
  1,null不是一个值,表示为空,不能用等号判断
  2,判断只能用`is null` 或者 `is not null`

3,and和or联合起来使用
  找出薪资大于1000的并且部门编号是20或30部门的员工。
  '例子1':select ename,sal,deptno from emp where sal > 1000 and deptno = 20 or deptno = 30; // 错误的
  '例子2':select ename,sal,deptno from emp where sal > 1000 and (deptno = 20 or deptno = 30); // 正确的。
  说明:例子1中,and后面的内容是一个判断的整体,优先级相同,当优先级不确定的时候使用小括号。

4,in和or联合使用--in等同于or
	找出工作岗位是MANAGER和SALESMAN的员工?
'例子1':select ename,job from emp where job = 'SALESMAN' or job = 'MANAGER';
'例子2':select ename,job from emp where job in('SALESMAN', 'MANAGER');
'例子3':select ename,job from emp where sal in(800, 5000); // in后面的值不是区
'例子4':select ename,job from emp where sal not in(800, 5000);
说明:
  1,in后面可以跟上具体值,指代的也是具体值,并不是一个区间。
  2,not in是不包括括号里面的具体值。

3,分组函数

函数名 含义
count 计数(数据记录条数,多少行,忽略null)
sum 求和
avg 平均值
max 最大值
min 最小值

所有函数都是对一个或几个字段的数据进行操作

1,找出工资总和?
 select sum(sal) from emp;	                       
2,找出最高工资?
 select max(sal) from emp;	                       
3,找出最低工资?
select min(sal) from emp;
4,找出平均工资?
 select avg(sal) from emp;
5,找出总人数?
select count(*) from emp;
select count(ename) from emp;
6,找出工资大于平均工资的人?
select ename,sal from emp where sal > avg(sal); //ERROR 1111 (HY000): Invalid use of group function
7,分组函数也能组合起来用:
select count(*),sum(sal),avg(sal),max(sal),min(sal) from emp;
说明:
  1,使用的方式就是在select后面,里面表示自己想要处理的字段,后续还能使用where进一步筛选数据
  2,分组函数也叫多行处理函数:输入多行,输出一行结果。
  3,分组函数自动忽略`NULL`值
  4,count(*)和count(具体的某个字段),他们有什么区别?
     count(*):不是统计某个字段中数据的个数,而是统计`总记录条数`。(和某个字段无关)
     count(comm): 表示统计comm字段中`不为NULL的数据总数量`。
  5,例子6中的语法错误,分组函数不能使用在where子句中。`原因在完整sql语句总结中查看`

4,单行处理函数

单行处理函数
	1,什么是单行处理函数?
		输入一行,输出一行。
	
	2,计算每个员工的年薪?
		select ename,(sal+comm)*12 as yearsal from emp;
		重点:所有数据库都是这样规定的,只要有NULL参与的运算结果一定是NULL。
		使用ifnull函数:
		select ename,(sal+ifnull(comm,0))*12 as yearsal from emp;
	
	3,if null() 空处理函数?
		ifnull(可能为NULL的数据,被当做什么处理) : 属于单行处理函数。
		select ename,ifnull(comm,0) as comm from emp;

5,分组查询

在SQL语句中若有`group by` 语句,那么在select语句后面只能跟`分组函数+参与分组的字段`。
	group by : 按照某个字段或者某些字段进行分组,字段中内容相同的分为一组,例如:部门,职位等等。
	having :  having是对分组之后的数据进行再次过滤。
	注意:1:分组函数一般都会和group by联合使用,这也是为什么它被称为分组函数的原因。
	      2:并且任何一个分组函数(count sum avg max min)都是在group by语句执行结束之后才会执行的。
	      3:当一条sql语句没有group by的话,整张表的数据会自成一组。

6,distinct去重

1、关于查询结果集的去重?
distinct 是对后面的字段所在的列进行比较,该列唯一。
mysql> select distinct job from emp; // distinct关键字去除重复记录。
+-----------+
| job       |
+-----------+
| CLERK     |
| SALESMAN  |
| MANAGER   |
| ANALYST   |
| PRESIDENT |
+-----------+        

mysql> select ename,distinct job from emp;
以上的sql语句是错误的。
记住:distinct只能出现在所有字段的最前面。
多个字段表示对所有字段联合去重。字段组合不同
就看作不同。

mysql> select distinct deptno,job from emp;
+--------+-----------+
| deptno | job       |
+--------+-----------+
|     20 | CLERK     |
|     30 | SALESMAN  |
|     20 | MANAGER   |
|     30 | MANAGER   |
|     10 | MANAGER   |
|     20 | ANALYST   |
|     10 | PRESIDENT |
|     30 | CLERK     |
|     10 | CLERK     |
+--------+-----------+

案例:统计岗位的数量?
select count(distinct job) from emp;

+---------------------+
| count(distinct job) |
+---------------------+
|                   5 |
+---------------------+

7,完整DQL语句的总结

	select                5
		..
	from                  1        
		..
	where                 2
		..
	group by              3
		..
	having                4
		..
	order by              6
		..
	limit                 7
说明:
  1:执行from找到需要操作的表
    `--->`where后面跟条件(一般是条件查询)对数据进行筛选`--->`得到的数据根据字段进行分组`--->`having对分组得到的数据二次筛选
    `--->`select得到需要展示的字段`--->`order by 展示数据的排列`--->`limit分页(仅MySQL数据库可用);
  2:总共分成了三大步,先是找到表,在是对表中数据筛选,最后是数据的展示。
  3:where后面不能使用分组函数,
    分组函数一般和group by 联合使用当没有group by 关键字的时候看作一组,其实是有分组的。分组函数的执行必须在group by 
    之后才行。根据上面的执行顺序是不可以的。

8,连接查询

1,什么是连接查询?
	多张表联合在一起查询。
2,连接查询的分类?
	a:根据语法出现的年代来划分的话,包括:
		SQL92(一些老的DBA可能还在使用这种语法。DBA:DataBase Administrator,数据库管理员)
		SQL99(比较新的语法)
	
	b:根据表的连接方式来划分,包括:
		⑴内连接:
			等值连接
			非等值连接
			自连接
		⑵外连接:
			左外连接(左连接)
			右外连接(右连接)
		⑶全连接(很少用!)
3,笛卡尔积现象:
    当两张表进行连接查询的时候,没有任何条件进行限制,最终的查询结果条数是两张表记录条数的乘积。
    避免笛卡尔积就必须要加入相应的限制条件。限制条件并不能减少sql语句的查询,不会提过效率,只是对查询出来后的数据进行筛选显示而已;

4.表的别名
  select e.ename,d.dname from emp e,dept d;
	表的别名有什么好处?
		第一:执行效率高。
		第二:可读性好。    

8-1:内连接

1,等值连接---连接条件是等量关系
  案例:查询每个员工的部门名称,要求显示员工名和部门名。

  a. SQL92:(太老,不用了)
	select 
		e.ename,d.dname
	from
		emp e, dept d
	where
		e.deptno = d.deptno;

  SQL99:(常用的)
	select 
		e.ename,d.dname
	from
		emp e
  inner join
		dept d
	on
		e.deptno = d.deptno;

	`inner可以省略的,带着inner目的是可读性好一些`
	select 
		e.ename,d.dname
	from
		emp e
	inner join
		dept d
	on
		e.deptno = d.deptno;
	
	语法:
		...
			A
	inner  join
			B
		on
			连接条件
		where
			...
	
	SQL99语法结构更清晰一些:表的连接条件和后来的where条件分离了。

2,非等值连接---连接条件中的关系是非等量关系。
    案例:找出每个员工的工资等级,要求显示员工名、工资、工资等级。
    mysql> select ename,sal from emp; e
  +--------+---------+
  | ename  | sal     |
  +--------+---------+
  | SMITH  |  800.00 |
  | ALLEN  | 1600.00 |
  | WARD   | 1250.00 |
  | JONES  | 2975.00 |
  | MARTIN | 1250.00 |
  | MILLER | 1300.00 |
  +--------+---------+

  mysql> select * from salgrade; s
  +-------+-------+-------+ 
  | GRADE | LOSAL | HISAL |
  +-------+-------+-------+
  |     1 |   700 |  1200 |
  |     2 |  1201 |  1400 |
  |     3 |  1401 |  2000 |
  |     4 |  2001 |  3000 |
  |     5 |  3001 |  9999 |
  +-------+-------+-------+

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

// inner可以省略
select 
	e.ename,e.sal,s.grade
from
	emp e
inner 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 |
      +--------+---------+-------+

3,自连接--一张表当作两张表看待,自己连接自己。
案例:找出每个员工的上级领导,要求显示员工名和对应的领导名。
mysql> select empno,ename,mgr from emp;
emp a 员工表
+-------+--------+------+
| empno | ename  | mgr  |
+-------+--------+------+
|  7369 | SMITH  | 7902 |
|  7499 | ALLEN  | 7698 |
|  7521 | WARD   | 7698 |
|  7566 | JONES  | 7839 |
|  7654 | MARTIN | 7698 |
|  7698 | BLAKE  | 7839 |
|  7782 | CLARK  | 7839 |
|  7788 | SCOTT  | 7566 |
|  7839 | KING   | NULL |
|  7844 | TURNER | 7698 |
|  7876 | ADAMS  | 7788 |
|  7900 | JAMES  | 7698 |
|  7902 | FORD   | 7566 |
|  7934 | MILLER | 7782 |
+-------+--------+------+
emp b 领导表
+-------+--------+
| empno | ename  |
+-------+--------+
|  7566 | JONES  |
|  7698 | BLAKE  |
|  7782 | CLARK  |
|  7788 | SCOTT  |
|  7839 | KING   |
|  7902 | FORD   |
+-------+--------+

员工的领导编号 = 领导的员工编号

select 
	a.ename as '员工名',b.ename as '领导名'
from
	emp a
inner 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  |
+--------+--------+

8-2:外连接

1,什么是外连接,和内连接有什么区别?
  内连接:
	假设A和B表进行连接,使用内连接的话,凡是A表和B表能够匹配上的记录查询出来,这就是内连接。
	AB两张表没有主副之分,两张表是平等的。	
		
	
  外连接:
	假设A和B表进行连接,使用外连接的话,AB两张表中有一张表是主表,一张表是副表,主要查询主表中
	的数据,捎带着查询副表,当副表中的数据没有和主表中的数据匹配上,副表自动模拟出NULL与之匹配。
		
  外连接的分类?
	左外连接(左连接):表示左边的这张表是主表。--- from 表1 left outer join 表二 on
	右外连接(右连接):表示右边的这张表是主表。--- from 表1 right outer join 表二 on
        `outer可以省略`
	
        左连接有右连接的写法,右连接也会有对应的左连接的写法。

----------------------案  例--------------------------------------------------------------------------------------------
		案例:找出每个员工的上级领导?(所有员工必须全部查询出来。)
		
		emp a 员工表
		+-------+--------+------+
		| empno | ename  | mgr  |
		+-------+--------+------+
		|  7369 | SMITH  | 7902 |
		|  7499 | ALLEN  | 7698 |
		|  7521 | WARD   | 7698 |
		|  7566 | JONES  | 7839 |
		|  7654 | MARTIN | 7698 |
		|  7698 | BLAKE  | 7839 |
		|  7782 | CLARK  | 7839 |
		|  7788 | SCOTT  | 7566 |
		|  7839 | KING   | NULL |
		|  7844 | TURNER | 7698 |
		|  7876 | ADAMS  | 7788 |
		|  7900 | JAMES  | 7698 |
		|  7902 | FORD   | 7566 |
		|  7934 | MILLER | 7782 |
		+-------+--------+------+

		emp b 领导表
		+-------+--------+
		| empno | ename  |
		+-------+--------+
		|  7566 | JONES  |
		|  7698 | BLAKE  |
		|  7782 | CLARK  |
		|  7788 | SCOTT  |
		|  7839 | KING   |
		|  7902 | FORD   |
		+-------+--------+
		
		内连接:
		select 
		        a.ename '员工', b.ename '领导'
		from
		        emp a
		join
		        emp b
		on
		        a.mgr = b.empno;
		
		外连接:(左外连接/左连接)
		select 
		        a.ename '员工', b.ename '领导'
		from
		        emp a
		left join
		        emp b
		on
		        a.mgr = b.empno;
		
		// outer是可以省略的。
		select 
		        a.ename '员工', b.ename '领导'
		from
		        emp a
		left outer join
		        emp b
		on
		        a.mgr = b.empno;
		
		外连接:(右外连接/右连接)
		select 
		        a.ename '员工', b.ename '领导'
		from
		        emp b
		right join
		        emp a
		on
		        a.mgr = b.empno;
		
		// outer可以省略。
		select 
		        a.ename '员工', b.ename '领导'
		from
		        emp b
		right outer join
		        emp a
		on
		        a.mgr = b.empno;
		
		+--------+-------+
		| 员工      | 领导    |
		+--------+-------+
		| SMITH  | FORD  |
		| ALLEN  | BLAKE |
		| WARD   | BLAKE |
		| JONES  | KING  |
		| MARTIN | BLAKE |
		| BLAKE  | KING  |
		| CLARK  | KING  |
		| SCOTT  | JONES |
		| KING   | NULL  |
		| TURNER | BLAKE |
		| ADAMS  | SCOTT |
		| JAMES  | BLAKE |
		| FORD   | JONES |
		| MILLER | CLARK |
		+--------+-------+
		
		外连接最重要的特点是:主表的数据无条件的全部查询出来。

----------------------------------------------三张表连接查询---------------------------------------------------
三张表怎么连接查询?
案例:找出每一个员工的部门名称以及工资等级。
EMP e
+-------+--------+---------+--------+
| empno | ename  | sal     | deptno |
+-------+--------+---------+--------+
|  7369 | SMITH  |  800.00 |     20 |
|  7499 | ALLEN  | 1600.00 |     30 |
|  7521 | WARD   | 1250.00 |     30 |
|  7566 | JONES  | 2975.00 |     20 |
|  7654 | MARTIN | 1250.00 |     30 |
|  7698 | BLAKE  | 2850.00 |     30 |
|  7782 | CLARK  | 2450.00 |     10 |
|  7788 | SCOTT  | 3000.00 |     20 |
|  7839 | KING   | 5000.00 |     10 |
|  7844 | TURNER | 1500.00 |     30 |
|  7876 | ADAMS  | 1100.00 |     20 |
|  7900 | JAMES  |  950.00 |     30 |
|  7902 | FORD   | 3000.00 |     20 |
|  7934 | MILLER | 1300.00 |     10 |
+-------+--------+---------+--------+
DEPT d
+--------+------------+----------+
| DEPTNO | DNAME      | LOC      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+
SALGRADE s
+-------+-------+-------+
| GRADE | LOSAL | HISAL |
+-------+-------+-------+
|     1 |   700 |  1200 |
|     2 |  1201 |  1400 |
|     3 |  1401 |  2000 |
|     4 |  2001 |  3000 |
|     5 |  3001 |  9999 |
+-------+-------+-------+

注意,解释一下:
	....
		A
	join
		B
	join
		C
	on
		...
	
	表示:A表和B表先进行表连接,连接之后A表继续和C表进行连接。

	select 
		e.ename,d.dname,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      | grade |
	+--------+------------+-------+
	| SMITH  | RESEARCH   |     1 |
	| ALLEN  | SALES      |     3 |
	| WARD   | SALES      |     2 |
	| JONES  | RESEARCH   |     4 |
	| MARTIN | SALES      |     2 |
	| BLAKE  | SALES      |     4 |
	| CLARK  | ACCOUNTING |     4 |
	| SCOTT  | RESEARCH   |     4 |
	| KING   | ACCOUNTING |     5 |
	| TURNER | SALES      |     3 |
	| ADAMS  | RESEARCH   |     1 |
	| JAMES  | SALES      |     1 |
	| FORD   | RESEARCH   |     4 |
	| MILLER | ACCOUNTING |     2 |
	+--------+------------+-------+
================================================三张表连接查询====================================================
案例:找出每一个员工的部门名称、工资等级、以及上级领导。
	select 
		e.ename '员工',d.dname,s.grade,e1.ename '领导'
	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 e1
	on
		e.mgr = e1.empno;

	+--------+------------+-------+-------+
	| 员工      | dname      | grade | 领导    |
	+--------+------------+-------+-------+
	| SMITH  | RESEARCH   |     1 | FORD  |
	| ALLEN  | SALES      |     3 | BLAKE |
	| WARD   | SALES      |     2 | BLAKE |
	| JONES  | RESEARCH   |     4 | KING  |
	| MARTIN | SALES      |     2 | BLAKE |
	| BLAKE  | SALES      |     4 | KING  |
	| CLARK  | ACCOUNTING |     4 | KING  |
	| SCOTT  | RESEARCH   |     4 | JONES |
	| KING   | ACCOUNTING |     5 | NULL  |
	| TURNER | SALES      |     3 | BLAKE |
	| ADAMS  | RESEARCH   |     1 | SCOTT |
	| JAMES  | SALES      |     1 | BLAKE |
	| FORD   | RESEARCH   |     4 | JONES |
	| MILLER | ACCOUNTING |     2 | CLARK |
	+--------+------------+-------+-------+

9,子查询

1. 什么是子查询?子查询都可以出现在哪里?
	select语句当中嵌套select语句,被嵌套的select语句是子查询。
	子查询可以出现在哪里?
		select
			..(select).
		from
			..(select).
		where
			..(select).

2,where子句中使用子查询
  案例:找出高于平均薪资的员工信息。

  第一步:找出平均薪资
	select avg(sal) from emp;
	+-------------+
	| avg(sal)    |
	+-------------+
	| 2073.214286 |
	+-------------+
  第二步:where过滤
	select * from emp where sal > 2073.214286;
	+-------+-------+-----------+------+------------+---------+------+--------+
	| EMPNO | ENAME | JOB       | MGR  | HIREDATE   | SAL     | COMM | DEPTNO |
	+-------+-------+-----------+------+------------+---------+------+--------+
	|  7566 | JONES | MANAGER   | 7839 | 1981-04-02 | 2975.00 | NULL |     20 |
	|  7698 | BLAKE | MANAGER   | 7839 | 1981-05-01 | 2850.00 | NULL |     30 |
	|  7782 | CLARK | MANAGER   | 7839 | 1981-06-09 | 2450.00 | NULL |     10 |
	|  7788 | SCOTT | ANALYST   | 7566 | 1987-04-19 | 3000.00 | NULL |     20 |
	|  7839 | KING  | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL |     10 |
	|  7902 | FORD  | ANALYST   | 7566 | 1981-12-03 | 3000.00 | NULL |     20 |
	+-------+-------+-----------+------+------------+---------+------+--------+
  第一步和第二步合并:
	select * from emp where sal > (select avg(sal) from emp);

3、from后面嵌套子查询

案例:找出每个部门平均薪水的等级。
第一步:找出每个部门平均薪水(按照部门编号分组,求sal的平均值)
select deptno,avg(sal) as avgsal from emp group by deptno;
+--------+-------------+
| deptno | avgsal      |
+--------+-------------+
|     10 | 2916.666667 |
|     20 | 2175.000000 |
|     30 | 1566.666667 |
+--------+-------------+
第二步:将以上的查询结果当做临时表t,让t表和salgrade s表连接,条件是:t.avgsal between s.losal and s.hisal
select 
	t.*,s.grade
from
	(select deptno,avg(sal) as avgsal from emp group by deptno) t
join
	salgrade s
on
	t.avgsal between s.losal and s.hisal;

+--------+-------------+-------+
| deptno | avgsal      | grade |
+--------+-------------+-------+
|     30 | 1566.666667 |     3 |
|     10 | 2916.666667 |     4 |
|     20 | 2175.000000 |     4 |
+--------+-------------+-------+


案例:找出每个部门平均的薪水等级。
第一步:找出每个员工的薪水等级。
select e.ename,e.sal,e.deptno,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;
+--------+---------+--------+-------+
| ename  | sal     | deptno | grade |
+--------+---------+--------+-------+
| SMITH  |  800.00 |     20 |     1 |
| ALLEN  | 1600.00 |     30 |     3 |
| WARD   | 1250.00 |     30 |     2 |
| JONES  | 2975.00 |     20 |     4 |
| MARTIN | 1250.00 |     30 |     2 |
| BLAKE  | 2850.00 |     30 |     4 |
| CLARK  | 2450.00 |     10 |     4 |
| SCOTT  | 3000.00 |     20 |     4 |
| KING   | 5000.00 |     10 |     5 |
| TURNER | 1500.00 |     30 |     3 |
| ADAMS  | 1100.00 |     20 |     1 |
| JAMES  |  950.00 |     30 |     1 |
| FORD   | 3000.00 |     20 |     4 |
| MILLER | 1300.00 |     10 |     2 |
+--------+---------+--------+-------+
第二步:基于以上结果,继续按照deptno分组,求grade平均值。
select 
	e.deptno,avg(s.grade)
from 
	emp e 
join 
	salgrade s 
on 
	e.sal between s.losal and s.hisal
group by
	e.deptno;

+--------+--------------+
| deptno | avg(s.grade) |
+--------+--------------+
|     10 |       3.6667 |
|     20 |       2.8000 |
|     30 |       2.5000 |
+--------+--------------+

3.4、在select后面嵌套子查询。
案例:找出每个员工所在的部门名称,要求显示员工名和部门名。

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

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 |
+--------+------------+

10,union操作符--合并select语句的结果

`UNION 内部的每个 SELEC 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。`

案例:找出工作岗位是SALESMAN和MANAGER的员工?
第一种:select ename,job from emp where job = 'MANAGER' or job = 'SALESMAN';
第二种:select ename,job from emp where job in('MANAGER','SALESMAN');
+--------+----------+
| ename  | job      |
+--------+----------+
| ALLEN  | SALESMAN |
| WARD   | SALESMAN |
| JONES  | MANAGER  |
| MARTIN | SALESMAN |
| BLAKE  | MANAGER  |
| CLARK  | MANAGER  |
| TURNER | SALESMAN |
+--------+----------+
第三种:union
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 |
+--------+----------+

两张不相干的表中的数据拼接在一起显示?
select ename from emp
union
select dname from dept;

+------------+
| ename      |
+------------+
| SMITH      |
| ALLEN      |
| WARD       |
| JONES      |
| MARTIN     |
| BLAKE      |
| CLARK      |
| SCOTT      |
| KING       |
| TURNER     |
| ADAMS      |
| JAMES      |
| FORD       |
| MILLER     |
| ACCOUNTING |
| RESEARCH   |
| SALES      |
| OPERATIONS |
+------------+

mysql> select ename,sal from emp
    -> union
    -> select dname from dept;
ERROR 1222 (21000): The used SELECT statements have a different number of columns
两张表查询数据想要相加必须列数相同。

`UNION和UNION ALL的区别`

UNION和UNION ALL关键字都是将两个结果集合并为一个,但这两者从使用和效率上来说都有所不同。

1、对重复结果的处理:UNION在进行表链接后会筛选掉重复的记录,Union All不会去除重复记录。

2、对排序的处理:Union将会按照字段的顺序进行排序;UNION ALL只是简单的将两个结果合并后就返回。

从效率上说,UNION ALL 要比UNION快很多,所以,如果可以确认合并的两个结果集中不包含重复数据且不需要排序时的话,那么就使用UNION ALL。

11,MySQL独有的分页查询

limit

1、limit是mysql特有的,其他数据库中没有,不通用。(Oracle中有一个相同的机制,叫做rownum)

2、limit取结果集中的部分数据,这时它的作用。

3、语法机制:
	limit startIndex, length
		startIndex表示起始位置,从0开始,0表示第一条数据。
		length表示取几个
	
	案例:取出工资前5名的员工(思路:降序取前5个)
		select ename,sal from emp order by sal desc;
		取前5个:
			select ename,sal from emp order by sal desc limit 0, 5;
			select ename,sal from emp order by sal desc limit 5;

4、limit是sql语句最后执行的一个环节:
	select                5
		...
	from                        1
		...                
	where                        2
		...        
	group by                3
		...
	having                4
		...
	order by                6
		...
	limit                        7
		...;

5、案例:找出工资排名在第4到第9名的员工?
	select ename,sal from emp order by sal desc limit 3,6;
	+--------+---------+
	| ename  | sal     |
	+--------+---------+
	| JONES  | 2975.00 |
	| BLAKE  | 2850.00 |
	| CLARK  | 2450.00 |
	| ALLEN  | 1600.00 |
	| TURNER | 1500.00 |
	| MILLER | 1300.00 |
	+--------+---------+

6、通用的标准分页sql?

每页显示3条记录:
第1页:0, 3
第2页:3, 3
第3页:6, 3
第4页:9, 3
第5页:12, 3

每页显示pageSize条记录:
第pageNo页:(pageNo - 1) * pageSize, pageSize

pageSize是什么?是每页显示多少条记录
pageNo是什么?显示第几页

java代码{
	int pageNo = 2; // 页码是2
	int pageSize = 10; // 每页显示10条
	
	limit (pageNo - 1) * pageSize, pageSize
}

12,补充

1.关于sql语句中的函数
除了上面着重介绍的分组函数(聚合函数)外,还有很多函数,可以对字符串,数字,日期等进行操作。使用的频率太低了。
2.列表2
3.列表3



这篇关于sql语法详解--DQL语句的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程