查询3_内连接

11、having(对分组后的信息进行过滤)
1.
having子句是用来对分组之后的数据进行过滤
因此使用having时通常都会先使用group by
2.
如果没有使用group by但使用了having则意味着having把所有的记录当做一组来进行过滤
select count(*)
from emp
having avg(sal)>1000
3. having子句出现的字段必须是分组后的整体信息
having子句不允许出现组内的详细信息
4. 
尽管select语句中可以出现别名但having语句中不能出现字段的别名,
只能使用最原始的字段
5.
where 和 having的异同
相同: 都是对数据过滤,保留有效的数据
不同: where是对原始的记录过滤,having是对分组后的记录过滤,两者顺序不同

where必须写在having前面,两者顺序不可颠倒,否则编译出错

select deptno,job, avg(sal) "平均工资",count(*) "部门人数",sum(sal) "部门总工资",min(sal) "部门最低工资"
	from emp
	group by deptno,job
	order by deptno;
select comm "奖金", count(*) "人数"
	from emp
	group by comm;--按照奖金分组
select max(sal) from emp;
--输出部门平均工资大于的部门的编号部门的平均工资
select deptno,avg(sal) "平均工资"
	from emp
	group by  deptno
	having avg(sal)>1500;
select deptno,avg(sal) "平均工资"
	from emp
	group by  deptno
	having deptno > 10;--true
select deptno,avg(sal) "平均工资"
	from emp
	group by  deptno
	having count(*) > 3;--true
select deptno,avg(sal) "平均工资"
	from emp
	group by  deptno
	having ename like '%A%';--error
select deptno "部门编号", avg(sal) "平均工资"
	from emp
	group by deptno
	having "部门编号">1;--error
--把名字不包含A的所有的员工按部门分组
--统计输出部门平均工资大于的部门的编号部门的平均工资
select deptno, avg(sal) "平均工资"
	from emp
	where ename not like '%A%'
	group by deptno
	having avg(sal) > 2000;
--把工资>2000
--统计输出部门平均工资大于的部门的编号部门的平均工资
select deptno, avg(sal) "平均工资", count(*) "部门工资>2000人数", max(sal) "部门最高工资"
	from emp
	where sal >2000	 --where 是对原始的记录过滤
	group by deptno
	having avg(sal) > 3000; --对分组之后的记录过滤
select deptno, avg(sal) "平均工资", count(*) "部门工资>2000人数", max(sal) "部门最高工资"
	from emp	
	group by deptno
	having avg(sal) > 3000
	where sal >2000;--error
--总结:所有select参数的顺序是不允许变化的,否则编译出错
having和where的异同
相同: 都是对数据过滤,保留有效的数据
不同: where是对原始的记录过滤,having是对分组后的记录过滤,两者顺序不同
where必须写在having前面,两者顺序不可颠倒,否则编译出错

select语句的基本结构
select select_list
into new_table_name
from table_list
where search_conditions
group by group_by_list
having search+condition
order by order_list [asc|desc]
select语句基本结构中包含了8个子句,这些子句的排列顺序是固定的。其中除select子句外,其他
子句都可以省略,但若出现必须按照基本结构中的顺序排列。


12、连接查询

定义:
将两个表或者两个以上的表以一定的连接条件连接起来从中检索出满足条件的数据
分类

内连接(重点+难点)
1. select ... from A, B 的用法
产生:
行数 A,B之积
列数:A和B之和
或者说把A表的每一条记录都和B表的每一条记录组合在一起形成一个笛卡尔积
或者说把B表的每一条记录都和A表的每一条记录组合在一起形成一个笛卡尔积
--emp 14行列dept 5行列产生的是一个笛卡尔积行列
--此时无任何连接条件
注意 select * from A,B和select * from B,A是一样的 
select * from emp, dept
 判断下面两个语句的输出结果是什么:

select * 
	from emp, dept
	where emp.deptno =10--输出的行数肯定是dept表行数的倍数
select * 
	from emp,  dept
	where dept.deptno =10--输出的行数肯定是emp表行数的倍数
2. select ... from A, B where ...的用法

对select ... from A, B 
例子:
--输出5行11列
select * from emp, dept
where empno = 7369
产生的笛卡尔积用where中的条件进行过滤

3. select ... from A join B on ...的用法

					select "E".ename "员工姓名", "D".dname "部门名称"
						from emp "E"--E D可以用中文替代
						join dept "D" -- join连接
						on "E".deptno = "D".deptno --on连接条件on不能省略有join就有on

4.SQL92标准和SQL99标准的区别

  select ... from A, B where ... 是SQL92标准

  select ... from A join B on ... 的比较  是SQL99标准
输出结果一样
推荐使用SQL99标准
1. sql99更容易理解
2. 在sql99标准中on和where可以做不同的分工
on指定连接条件
where对连接后的临时表进行过滤

select * 
	from emp,dept
	where emp.deptno=dept.deptno
--等价于
select *
	from emp
	join dept
	on emp.deptno=dept.deptno

例子:
-- 1.把工资大于的员工姓名和部门名称输出

--sql92的实现
select "E".ename "员工姓名", "D".dname "部门名称"
	from emp "E", dept "D"--起别名是用于查询的优化
	where "E".sal > 2000 and "E".deptno = "D".deptno
--sql99实现
select "E".ename "员工姓名", "D".dname "部门名称"
	from emp "E"
	join dept "D"
	on "E".deptno = "D".deptno
	where "E".sal > 2000
-- 2.把工资大于的员工姓名和部门名称输出和工资等级(三个表连接)
--sql99实现
select "E".ename "员工姓名", "D".dname "部门名称", "S".grade "工资等级"
	from emp "E"
	join dept "D"
	on "E".deptno = "D".deptno
	join SALGRADE "S"
	on "E".sal >= "S".LOSAL and "E".sal <= "S".HISAL
	where "E".sal > 2000
--sql92实现
select "E".ename "员工姓名", "D".dname "部门名称", "S".grade "工资等级"
	from emp "E", dept "D", SALGRADE "S"
	where "E".deptno = "D".deptno and ("E".sal >= "S".LOSAL and "E".sal <= "S".HISAL)
	 and "E".sal > 2000
问题:以上where是否可以写在join前面
否 以下查询是错误的

select "E".ename "员工姓名", "D".dname "部门名称", "S".grade "工资等级"
	from emp "E"
	where "E".sal > 2000
	join dept "D"
	on "E".deptno = "D".deptno
	join SALGRADE "S"
	on "E".sal >= "S".LOSAL and "E".sal <= "S".HISAL--erro

select * 
	from emp,  dept
	where dept.deptno =10--输出的行数肯定是emp表行数的倍数
--等价于
select * 
	from emp
	join dept
	on 1=1
	where dept.deptno =10

以下等价错误

select * 
		from emp
		join dept
		on emp.deptno=dept.deptno--on指定的是连接条件
		having dept.deptno =10-- 错误having是对分组后的数据过滤


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值