数据分组和连接查询

1.排序(默认升序)

按照工资升序,找出员工名和薪资
select
ename,sal
from
emp
order by
sal;

注意:默认是升序。怎么指定升序或者降序呢?asc表示升序,desc表示降序。
select ename , sal from emp order by sal; // 升序
select ename , sal from emp order by sal asc; // 升序
select ename , sal from emp order by sal desc; // 降序。

按照工资的降序排列,当工资相同的时候再按照名字的升序排列。
select ename,sal from emp order by sal desc , ename asc;
注意:越靠前的字段越能起到主导作用。只有当前面的字段无法完成排序的时候,才会启用后面的字段。

找出工作岗位是SALESMAN的员工,并且要求按照薪资的降序排列。
select
ename,job,sal
from
emp
where
job = ‘SALESMAN’
order by
sal desc;

执行顺序
select
字段 3
from
表名 1
where
条件 2
order by
… 4

order by是最后执行的。

2.分组函数
count 计数
sum 求和
avg 平均值
max 最大值
min 最小值
记住:所有的分组函数都是对“某一组”数据进行操作的。

找出工资总和?
select sum(sal) from emp;
找出最高工资?
select max(sal) from emp;
找出最低工资?
select min(sal) from emp;
找出平均工资?
select avg(sal) from emp;
找出总人数?
select count(*) from emp;
select count(ename) from emp;

分组函数一共5个。
分组函数还有另一个名字:多行处理函数。
多行处理函数的特点:输入多行,最终输出的结果是1行。

分组函数自动忽略NULL:
select sum(comm) from emp where comm is not null; // 不需要额外添加这个过 滤 条件。sum函数自动忽略NULL。

找出工资高于平均工资的员工?
select avg(sal) from emp; // 平均工资
±------------+
| avg(sal) |
±------------+
| 2073.214286 |
±------------+

select ename,sal from emp where sal > avg(sal); //ERROR 1111 (HY000): Invalid use of group function
原因:SQL语句当中有一个语法规则,分组函数不可直接使用在where子句当中。why????
因为group by是在where执行之后才会执行的。
			
			select			5
				..			
			from			1
				..
			where			2
				..
			group by		3
				..
			having			4
				..
			order by			6
				..

那怎么解决?
第一步:找出平均工资
select avg(sal) from emp;
第二步:找出高于平均工资的员工
select ename,sal from emp where sal > (select avg(sal) from emp);

分组函数也能组合起来用:
select count(*),sum(sal),avg(sal),max(sal),min(sal) from emp;

	+----------+----------+-------------+----------+----------+
	| count(*) | sum(sal) | avg(sal)    | max(sal) | min(sal) |
	+----------+----------+-------------+----------+----------+
	|       14 | 29025.00 | 2073.214286 |  5000.00 |   800.00 |
	+----------+----------+-------------+----------+----------+

3.单行处理函数:

4.count()和count(具体的某个字段)的区别
count(
):不是统计某个字段中数据的个数,而是统计总记录条数。(和某个字段无关)
count(comm): 表示统计comm字段中不为NULL的数据总数量。

5.group by 和 having

group by : 按照某个字段或者某些字段进行分组。
having : having是对分组之后的数据进行再次过滤。
案例:找出每个工作岗位的最高薪资。
select max(sal),job from emp group by job;

注意:分组函数一般都会和group by联合使用,这也是为什么它被称为分组函数的原因。并且任何一个分组函数(count sum avg max min)都是在group by语句执行结束之后才会执行的。
当一条sql语句没有group by的话,整张表的数据会自成一组。

select ename,max(sal),job from emp group by job;
以上在mysql当中,查询结果是有的,但是结果没有意义,在Oracle数据库当中会报错。语法错误。Oracle的语法规则比MySQL语法规则严谨。
***记住一个规则:当一条语句中有group by的话,select后面只能跟分组函数和参与分组的字段。

每个工作岗位的平均薪资?
select job,avg(sal) from emp group by job;

多个字段能不能联合起来一块分组?
案例:找出每个部门不同工作岗位的最高薪资。
select
deptno,job,max(sal)
from
emp
group by
deptno,job;

找出每个部门的最高薪资,要求显示薪资大于2900的数据。

	第一步:找出每个部门的最高薪资
	select max(sal),deptno from emp group by deptno;

	第二步:找出薪资大于2900
	select max(sal),deptno from emp group by deptno having max(sal) > 2900; // 这种方式效率低。

	select max(sal),deptno from emp where sal > 2900 group by deptno;  // 效率较高,建议能够使用where过滤的尽量使用where。

找出每个部门的平均薪资,要求显示薪资大于2000的数据。

第一步:找出每个部门的平均薪资
select deptno,avg(sal) from emp group by deptno;

第二步:要求显示薪资大于2000的数据
select deptno,avg(sal) from emp group by deptno having avg(sal) > 2000;	

where后面不能使用分组函数:
	select deptno,avg(sal) from emp where avg(sal) > 2000 group by deptno;	// 错误了。
	这种情况只能使用having过滤。

6.总结一个完整的DQL语句怎么写?

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

7.关于查询结果集的去重?
mysql> select distinct job from emp; // distinct关键字去除重复记录。

mysql> select ename,distinct job from emp;
以上的sql语句是错误的。
记住:distinct只能出现在所有字段的最前面。

mysql> select distinct deptno,job from emp;
deptno和job两个联合起来去重

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

8.连接查询

8.1、什么是连接查询?
在实际开发中,大部分的情况下都不是从单表中查询数据,一般都是多张表联合查询取出最终的结果。
在实际开发中,一般一个业务都会对应多张表,比如:学生和班级,起码两张表。
stuno stuname classno classname
-----------------------------------------------------------------------------------
1 zs 1 北京大兴区亦庄经济技术开发区第二中学高三1班
2 ls 1 北京大兴区亦庄经济技术开发区第二中学高三1班

学生和班级信息存储到一张表中,结果就像上面一样,数据会存在大量的重复,导致数据的冗余。

8.2 连接查询的分类?
根据语法出现的年代来划分的话,包括:
SQL92(一些老的DBA可能还在使用这种语法。DBA:DataBase Administrator,数据库管理员)
SQL99(比较新的语法)

根据表的连接方式来划分,包括:
	内连接:
		等值连接
		非等值连接
		自连接
	外连接:
		左外连接(左连接)
		右外连接(右连接)
	全连接(这个不讲,很少用!)

8.3 在表的连接查询方面有一种现象被称为:笛卡尔积现象。(笛卡尔乘积现象)

案例:找出每一个员工的部门名称,要求显示员工名和部门名。
EMP表
±-------±-------+
| ename | deptno |
±-------±-------+
| SMITH | 20 |
| ALLEN | 30 |
| WARD | 30 |
| JONES | 20 |
| MARTIN | 30 |
| BLAKE | 30 |
| CLARK | 10 |
| SCOTT | 20 |
| KING | 10 |
| TURNER | 30 |
| ADAMS | 20 |
| JAMES | 30 |
| FORD | 20 |
| MILLER | 10 |
±-------±-------+
DEPT表
±-------±-----------±---------+
| DEPTNO | DNAME | LOC |
±-------±-----------±---------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
±-------±-----------±---------+

select ename,dname from emp,dept;
±-------±-----------+
| ename | dname |
±-------±-----------+
| SMITH | ACCOUNTING |
| SMITH | RESEARCH |
| SMITH | SALES |
| SMITH | OPERATIONS |
| ALLEN | ACCOUNTING |
| ALLEN | RESEARCH |
| ALLEN | SALES |
| ALLEN | OPERATIONS |

56 rows in set (0.00 sec)

笛卡尔积现象:当两张表进行连接查询的时候,没有任何条件进行限制,最终的查询结果条数是两张表记录条数的乘积。

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

8.4 怎么避免笛卡尔积现象?当然是加条件进行过滤。
思考:避免了笛卡尔积现象,会减少记录的匹配次数吗?
不会,次数还是56次。只不过显示的是有效记录。

8.5 内连接之等值连接:最大特点是:条件是等量关系。

案例:查询每个员工的部门名称,要求显示员工名和部门名。

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
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
join
B
on
连接条件
where

SQL99语法结构更清晰一些:表的连接条件和后来的where条件分离了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值