sql 语句系列(多表之链)[八百章之第三章]
新增连接查询而不影响其他连接查询
请看图:

这种情况我们一般会使用左连接的方式。
select e.ENAME,d.LOC,eb.RECEIVED
from emp e join dept d
on(e.DEPTNO=d.DEPTNO) left join emp_bonus eb
on(eb.EMPNO=e.EMPNO)
order by 2
上面这种可以实现的,但是不利于我们在写code语句中的复用。
下面是一种标量子查询我的方式,可以帮助我们复用部分sql。
select e.ENAME,d.LOC,(select eb.RECEIVED from emp_bonus eb where e.EMPNO=eb.EMPNO) as RECEIVED
from emp e join dept d
on(e.DEPTNO=d.DEPTNO)
order by 2
这里原理很简单,其实就是先设置了RECEIVED 行然后去查询。
同样这里有限制就是RECEIVED 查询出来必须只有一个结果,因为开辟了一个空间。
在未来第600章中会介绍如果针对查询出多行的问题。
组合使用连接查询与聚合函数
select e.DEPTNO,e.EMPNO,e.ENAME,e.SAL,e.SAL*case
when eb.TYPE=1 then 0.1
when eb.TYPE=2 then 0.2
when eb.TYPE=3 then 0.3
end as bonus
from EMP e,emp_bonus eb
where e.EMPNO=eb.EMPNO
and e.DEPTNO=10

现在只需要看到上图的表。
现在有一个需要,就是要统计上面部门为10的SAL 和 bonus。
这个时候一般想到的是聚合函数。
select x.DEPTNO,sum(x.SAL) as total_sum,sum(x.bonus) as total_bonus from
(select e.DEPTNO,e.EMPNO,e.ENAME,e.SAL,e.SAL*case
when eb.TYPE=1 then 0.1
when eb.TYPE=2 then 0.2
when eb.TYPE=3 then 0.3
end as bonus
from EMP e,emp_bonus eb
where e.EMPNO=eb.EMPNO
and e.DEPTNO=10) x
group by x.DEPTNO

得到的结果为错误的。因为有人得到两次奖励:

那么可能会这样写:
(select e.DEPTNO,e.EMPNO,e.ENAME,e.SAL,e.SAL*case
when eb.TYPE=1 then 0.1
when eb.TYPE=2 then 0.2
when eb.TYPE=3 then 0.3
end as bonus
from EMP e,emp_bonus eb
where e.EMPNO=eb.EMPNO
and e.DEPTNO=10) x
group by x.DEPTNO
排除掉sal中相同的项增加,但是万一有人sal相同怎么办?这肯定是一个问题。还有一个问题就是如果这个部门有一部分人如果没有得到bonus怎么办?也就是说有一部分SAL没显示出来
select x.DEPTNO, d.total_sum,sum(x.bonus) as total_bonus from
(select e.DEPTNO,e.EMPNO,e.ENAME,e.SAL,e.SAL*case
when eb.TYPE=1 then 0.1
when eb.TYPE=2 then 0.2
when eb.TYPE=3 then 0.3
end as bonus
from EMP e,emp_bonus eb
where e.EMPNO=eb.EMPNO
and e.DEPTNO=10
) x,(select DEPTNO,sum(EMP.SAL) as total_sum from EMP where EMP.DEPTNO=10 group by EMP.DEPTNO) d
where d.DEPTNO=x.DEPTNO
group by x.DEPTNO,d.total_sum
我们可以通过之查询出sum(x.bonus),然后再外表连接出d.total_sum。
优化一下:
select e.DEPTNO,d.total_sum,sum(e.SAL*case
when eb.TYPE=1 then 0.1
when eb.TYPE=2 then 0.2
when eb.TYPE=3 then 0.3
end) as bonus
from EMP e,emp_bonus eb,(select DEPTNO,sum(EMP.SAL) as total_sum from EMP where DEPTNO=10 group by DEPTNO) d
where e.EMPNO=eb.EMPNO and e.DEPTNO=d.DEPTNO
group by e.DEPTNO,d.total_sum
优化的依据是:
出现两个EMP.DEPTNO=10 条件可以合并,第二点就是没必要查e.ENAME这些,可以直接合并。
有些人可能使用sum over 函数去写:
select e.DEPTNO,sum(distinct e.SAL) over (partition by e.deptno) as total_sum,sum(e.SAL*case
when eb.TYPE=1 then 0.1
when eb.TYPE=2 then 0.2
when eb.TYPE=3 then 0.3
end) over (partition by e.deptno) as bonus
from EMP e left join emp_bonus eb on e.EMPNO=eb.EMPNO
where e.DEPTNO=10
我上面使用了外连接,是避免这个部门有一部分人如果没有得到bonus。
其中有两个问题,一个就是over 语句中不能包括distinct了,第二个就是不同人empno 中可能sal相同。
所以这种情况尽量不要去使用这种方式。
sql 语句系列(多表之链)[八百章之第三章]的更多相关文章
- sql 语句系列(null 值处理)[八百章之第二章]
查找只存在一个表中的数据 有两张表: EMP: select * from emp DEPT: 他们有共同的属性:deptno 现在要查询EMP 中的deptno不等于DEPTNO的deptno项. ...
- oracle一条sql语句统计充值表中今天,昨天,前天三天充值记录
select NVL(sum(case when create_date_time>=to_date('2014-11-24 00:00:00','yyyy-mm-dd hh24:mi:ss') ...
- sql语句中----删除表数据drop、truncate和delete的用法
sql语句中----删除表数据drop.truncate和delete的用法 --drop drop table tb --tb表示数据表的名字,下同 删除内容和定义,释放空间.简单来说就是把整 ...
- SQL语句查询某表的所有字段及数据类型
SQL语句查询某表的所有字段及数据类型 SELECT name AS column_name , TYPE_NAME(system_type_id) AS column_type , max_leng ...
- (转载)用SQL语句创建Access表
<来源网址:http://www.delphifans.com/infoview/Article_220.html>用SQL语句创建Access表 很久以前弄的,用了一天的时间,没有什么技 ...
- 使用sql语句获取数据库表的信息
下面的sql语句可以查看表的信息.其中modify_date和create_date可以根据表的修改时间来查看.如果不需要删除后,就能看到所有表的字段信息 ) PERCENT d.name AS 表名 ...
- [转]关于oracle sql语句查询时表名和字段名要加双引号的问题
oracle初学者一般会遇到这个问题. 用navicat可视化创建了表,可是就是不能查到! 后来发现②语句可以查询到 ①select * from user; 但是,我们如果给user加上双引 ...
- SQL语句之 多表管理
SQL语句之 多表管理 一个数据库内通常会有不止一张表,有时候我们要把多张表联系起来,这就需要用到多表管理的语句. 1.外键约束 一个表中的非主键字段,如果在另外一张表中是主键,那么这个字段我们叫它做 ...
- ylb:sql语句重命名表名和列名
ylbtech-SQL Server:SQL Server-sql语句重命名表名和列名 sql语句重命名表名和列名 ylb:sql语句重命名表名和列名 返回顶部 一.更改数据库名 sp_rena ...
随机推荐
- for循环的应用
for循环的应用:迭代法,穷举法. 一.迭代法:(有一定规律) 每次循环都是从上次运算结果中获得数据,本次运算的结果都是要为下次运算做准备. 例:1.100以内所有数的和. int sum = 0;f ...
- zepto.js和jquery.js函数比较有什么优点?
1.Zepto.js 是专门为现代智能手机浏览器退出的 Javascript 框架, 拥有和jQuery相似的语法, 但是和jQuery相比下来, 他有很多优点, 大小方面 , 压缩后的 zepto. ...
- failed to load main-class manifest attribute(运行jar包出错)
原因描述:MANIFEST.MF文件中的Main-Class配置不正确或格式不正确 检查方式:以WinRarR的方式打开jar包,如图所示, 点击进入箭头所指的META-INF文件夹 将MAN ...
- css之制作三角形
箭头向上三角形 #triangle-up { width: 0; height: 0; border-left: 50px solid transparent; border-right: 50px ...
- 使用Handler的步骤
使用Handler的大致流程: 1.首先创建一个Handler对象,可以直接使用Handler无参构造函数创建Handler对象,也可以继承Hander类,重写HandleMessage方法来创建Ha ...
- P1102 A-B 数对
P1102题库链接:https://www.luogu.org/problem/P1102 难度:普及- 算法标签:模拟,数论,排序,HASH,概率论,二分查找 1.朴素 O(n^2) 得分76 将输 ...
- springboot创建,自动装配原理分析,run方法启动
使用IDEA快速创建一个springboot项目 创建Spring Initializr,然后一直下一步下一步直至完成 选择web,表示创建web项目 运行原理分析 我们先来看看pom.xml文件 核 ...
- localstorage浏览器储存
需求 a.html页面生成订单信息,b.html中调用. 通过不操作数据库,直接在浏览器自带的数据库中进行操作,当然主要是对Json数据的操作. a.html代码部分: <!--html--&g ...
- 关于Js的那些面试题
1.javascript的typeof返回哪些数据类型 number string boolean Object function underfind 2.例举3种强制类型转换和2种隐式类型转换?强制 ...
- 支持IE6、IE7、IE8等低端浏览器的简化版vue
最近研究Vue的底层原理,写了一个简化版的Vue,可以在支持IE6.IE7.IE8等低端浏览器运行.由于低端浏览器不支持对象属性定义,所以设置属性不支持直接赋值,需要调用虚拟机实例的set方法.目前只 ...