=======================================================================================
========================识别和消除笛卡尔积=============================
=======================================================================================
这种问题我在实际的问题中也遇到过,开始一直不知道怎么回事,数据会串行?
笛卡尔积,也就是笛卡尔乘积,因此如果是普通的两张表连接,就是将2张表乘起来显示。
等值连接就是在笛卡尔乘积的基础上剔除不相等的记录。
select e.ename, d.loc
from emp e, dept d
where e.deptno = 10;
由于查询结果是在两个表中出现的,所以有可能出现笛卡尔积现象。
解决方法:用等值附加条件。
select e.emp e, dept d
from emp e, dept d
where e.deptno = 10
and d.deptno = e.deptno;
这样的结果会通过d.deptno = e.deptno过滤掉因为笛卡尔积产生的交叉结果。
=======================================================================================
=====================================聚集和连接====================================
=======================================================================================
当处理聚集与链接混合操作时,一定要小心,如果链接产生重复行,可以有两种方法来避免聚集函数计算错误。
解决方法:只要在调用聚合函数时使用关键字distinct,这样每一个值只参与计算一次;
select deptno,
sum(distinct sal) as total_sal, #关键的去重distinct
sum(bonus) as total_bonus
from (select e.empno,
e.ename,
e.sal,
e.deptno,
e.sal * (case when eb.type = 1 then .1
when eb.type = 2 then .2
else .3 end) as bonus
from emp e, emp_bonus eb
where e.empno = eb.empno
and e.deptno = 10) x
group by deptno;
=======================================================================================
=====================================从多个表中返回丢失的数据==========================
=======================================================================================
解决方法:使用基于公共值的完全外链接返回两个表中丢失的数据。
select d.deptno, d.dname, e.ename
from dept d full outer join emp e
on (d.deptno = e.deptno);
替代:full outer join
select d.deptno, d.dname, e.ename
from dept d left outer join emp e
on (d.deptno = e.deptno);
union
select d.deptno, d.dname, e.ename
from dept d right outer join emp e
on (d.deptno = e.deptno);
=======================================================================================
=====================================从多个表中返回丢失的数据==========================
=======================================================================================
null值永远不会等于或不等于任何值,也包括null值自己,但是需要像计算实际值一样计算可为空列的返回值。
select ename, comm
from emp
where coalesce(comm, 0) < (select comm
from emp
========================识别和消除笛卡尔积=============================
=======================================================================================
这种问题我在实际的问题中也遇到过,开始一直不知道怎么回事,数据会串行?
笛卡尔积,也就是笛卡尔乘积,因此如果是普通的两张表连接,就是将2张表乘起来显示。
等值连接就是在笛卡尔乘积的基础上剔除不相等的记录。
select e.ename, d.loc
from emp e, dept d
where e.deptno = 10;
由于查询结果是在两个表中出现的,所以有可能出现笛卡尔积现象。
解决方法:用等值附加条件。
select e.emp e, dept d
from emp e, dept d
where e.deptno = 10
and d.deptno = e.deptno;
这样的结果会通过d.deptno = e.deptno过滤掉因为笛卡尔积产生的交叉结果。
=======================================================================================
=====================================聚集和连接====================================
=======================================================================================
当处理聚集与链接混合操作时,一定要小心,如果链接产生重复行,可以有两种方法来避免聚集函数计算错误。
解决方法:只要在调用聚合函数时使用关键字distinct,这样每一个值只参与计算一次;
select deptno,
sum(distinct sal) as total_sal, #关键的去重distinct
sum(bonus) as total_bonus
from (select e.empno,
e.ename,
e.sal,
e.deptno,
e.sal * (case when eb.type = 1 then .1
when eb.type = 2 then .2
else .3 end) as bonus
from emp e, emp_bonus eb
where e.empno = eb.empno
and e.deptno = 10) x
group by deptno;
=======================================================================================
=====================================从多个表中返回丢失的数据==========================
=======================================================================================
解决方法:使用基于公共值的完全外链接返回两个表中丢失的数据。
select d.deptno, d.dname, e.ename
from dept d full outer join emp e
on (d.deptno = e.deptno);
替代:full outer join
select d.deptno, d.dname, e.ename
from dept d left outer join emp e
on (d.deptno = e.deptno);
union
select d.deptno, d.dname, e.ename
from dept d right outer join emp e
on (d.deptno = e.deptno);
=======================================================================================
=====================================从多个表中返回丢失的数据==========================
=======================================================================================
null值永远不会等于或不等于任何值,也包括null值自己,但是需要像计算实际值一样计算可为空列的返回值。
select ename, comm
from emp
where coalesce(comm, 0) < (select comm
from emp
where ename = 'WARD');
笛卡尔积:参考http://sunmoonrili.blog.51cto.com/5265851/957112
参考文献:SQL.Cookbook