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

请看图:



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

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. Android开发之《ffmpeg解码mjpeg视频流》

    MJPEG格式和码流分析,MJPEG格式的一些简介 FFmpeg解码USB摄像头MJPEG输出:http://blog.csdn.net/light_in_dark/article/details/5 ...

  2. 学习和使用 Styled Layer Descriptor SLD样式文件

    1. SLD 文件大致作用,可以浏览下示意图: 点要素的符号化:http://docs.geoserver.org/stable/en/user/styling/sld-cookbook/points ...

  3. CF_Edu.#51_Div.2_1051F_The Shortest Statement

    F. The Shortest Statement time limit per test:4 seconds memory limit per test:256 megabytes input:st ...

  4. 概念--Maven仓库

    转:Maven:mirror和repository 区别 Tip: 默认中央仓库的地址:https://repo.maven.apache.org/maven2 1.Maven仓库主要有2种 remo ...

  5. 吴裕雄--天生自然 python开发学习笔记:下载python离线安装whl文件链接

    https://www.lfd.uci.edu/~gohlke/pythonlibs/

  6. R (Ani Katchova) · Eric

    首先介绍一下Ani Katchova的R教程,然后再继续总结Advanced R. R introduction setwd("path")设置工作路径 mydata<-re ...

  7. ypoj 2286 佳佳买菜

    题目名称:佳佳买菜 描述 佳佳是我们的ACM社团的副社长,她感觉得自己没存在感,so-由于实验室要聚餐了,佳佳决定买点菜,来做菜给大家吃.佳佳喜欢吃娃娃菜,于是她来到买菜的地方.佳佳:我要10斤娃娃菜 ...

  8. SGD与Adam识别MNIST数据集

    几种常见的优化函数比较:https://blog.csdn.net/w113691/article/details/82631097 ''' 基于Adam识别MNIST数据集 ''' import t ...

  9. Flutter调研(1)-Flutter基础知识

    工作需要,因客户端有部分页面要使用flutter编写,需要QA了解一下flutter相关知识,因此,做了flutter调研,包含安装,基础知识与demo编写,第二部分是安装与环境配置. —— Flut ...

  10. c++中的 const 关键字

    知识回顾:C语言中 const const 修饰的变量是 只读的,本质上还是变量:(只读变量:可以通过指针修改只读变量中的值) const 修饰的局部变量在栈上分配空间: const 修饰的全局变量在 ...