sql 語句系列(多表之鏈)[八百章之第三章]

新增鏈接查詢而不影響其餘鏈接查詢

請看圖:

這種狀況咱們通常會使用左鏈接的方式。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 查詢出來必須只有一個結果,由於開闢了一個空間。code

在將來第600章中會介紹若是針對查詢出多行的問題。blog

組合使用鏈接查詢與聚合函數

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

如今只須要看到上圖的表。it

如今有一個須要,就是要統計上面部門爲10的SAL 和 bonus。io

這個時候通常想到的是聚合函數。class

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

(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相同。 因此這種狀況儘可能不要去使用這種方式。

相關文章
相關標籤/搜索