新增连接查询而不影响其他连接查询

请看图:



这种情况我们一般会使用左连接的方式。

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 语句系列(多表之链)[八百章之第三章]的更多相关文章

  1. sql 语句系列(null 值处理)[八百章之第二章]

    查找只存在一个表中的数据 有两张表: EMP: select * from emp DEPT: 他们有共同的属性:deptno 现在要查询EMP 中的deptno不等于DEPTNO的deptno项. ...

  2. oracle一条sql语句统计充值表中今天,昨天,前天三天充值记录

    select NVL(sum(case when create_date_time>=to_date('2014-11-24 00:00:00','yyyy-mm-dd hh24:mi:ss') ...

  3. sql语句中----删除表数据drop、truncate和delete的用法

    sql语句中----删除表数据drop.truncate和delete的用法 --drop drop table  tb   --tb表示数据表的名字,下同 删除内容和定义,释放空间.简单来说就是把整 ...

  4. SQL语句查询某表的所有字段及数据类型

    SQL语句查询某表的所有字段及数据类型 SELECT name AS column_name , TYPE_NAME(system_type_id) AS column_type , max_leng ...

  5. (转载)用SQL语句创建Access表

    <来源网址:http://www.delphifans.com/infoview/Article_220.html>用SQL语句创建Access表 很久以前弄的,用了一天的时间,没有什么技 ...

  6. 使用sql语句获取数据库表的信息

    下面的sql语句可以查看表的信息.其中modify_date和create_date可以根据表的修改时间来查看.如果不需要删除后,就能看到所有表的字段信息 ) PERCENT d.name AS 表名 ...

  7. [转]关于oracle sql语句查询时表名和字段名要加双引号的问题

    oracle初学者一般会遇到这个问题.   用navicat可视化创建了表,可是就是不能查到!   后来发现②语句可以查询到 ①select * from user; 但是,我们如果给user加上双引 ...

  8. SQL语句之 多表管理

    SQL语句之 多表管理 一个数据库内通常会有不止一张表,有时候我们要把多张表联系起来,这就需要用到多表管理的语句. 1.外键约束 一个表中的非主键字段,如果在另外一张表中是主键,那么这个字段我们叫它做 ...

  9. ylb:sql语句重命名表名和列名

    ylbtech-SQL Server:SQL Server-sql语句重命名表名和列名 sql语句重命名表名和列名 ylb:sql语句重命名表名和列名 返回顶部 一.更改数据库名    sp_rena ...

随机推荐

  1. bubble chart|Matrix Scatter|Overlay Scatter|Scatterplots|drop-line|box plot|Stem-and-leaf plot|Histogram|Bar chart|Pareto chart|Pie chart|doughnut chart|

    应用统计学 对类别数据要分类处理: Bar chart复式条形图便于对比: Pareto chart:对类别变量依据频数高低排列: Pie chart:饼图用于一个样本,可以区分类别数据 doughn ...

  2. 为何印度打车软件Ola,也难逃“资本合并”命运?

    从全球市场来看,共享经济已经引发了多场具有颠覆性的风暴.尤其是在与大众关系紧密的衣食住行方面,诞生了具有强势影响力的独角兽企业.如,共享打车企业Uber.共享房屋出租企业Airbnb等.而鉴于每个国家 ...

  3. win7 任务栏 无法固定文件夹和文件 解决方法

    2010年开始使用win7,一直都在用一个功能,把常用的文件夹和文件都直接锁定到任务栏,方便使用. 最近这个功能一直有问题,开始只是重启以后,以前固定的文件没有了,这个也懒的去弄它,没了在添加一次. ...

  4. NEWMING

    这里只是列举一些常用的文件操作命令. cd 跳转切换目录 # 格式:cd dirname 比如在打开用户主目录盘下的 myidoc 文件夹 cd ~/myidoc 跳转到当前目录的上一级 cd ../ ...

  5. 手把手教你利用Jenkins持续集成iOS项目

    前言 众所周知,现在App的竞争已经到了用户体验为王,质量为上的白热化阶段.用户们都是很挑剔的.如果一个公司的推广团队好不容易砸了重金推广了一个APP,好不容易有了一些用户,由于一次线上的bug导致一 ...

  6. Kubernetes集群部署DNS插件

    准备 kube-dns 相关镜像 准备 kube-dns 相关 yaml 文件 系统预定义的 RoleBinding 配置 kube-dns 相关服务 检查 kube-dns 功能 kube-dns ...

  7. POI之下载模板(或各种文件)

    该例基于Nutz框架 前台代码: <a href="" id="errordownload" onclick="downloadErrorLog ...

  8. C++走向远洋——40(第九周,深复制体验)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  9. 那些年,我的前端/Java后端书单

    全文为这些年,我曾阅读.深入理解过(或正在阅读学习.即将阅读)的一些优秀经典前端/Java后端书籍.全文为纯原创,且将持续更新,未经许可,不得进行转载.当然,如果您喜欢这篇文章,可以动手点点赞或者收藏 ...

  10. 简单谈谈HashMap

    概述 面试Java基础,HashMap可以说是一个绕不过去的基础容器,哪怕其他容器都不问,HashMap也是不能不问的. 除了HashMap,还有HashTable跟ConcurrentHashMap ...