問題:要在包含多個表的查詢中執行聚集運算,要確保表間連線不能使聚集運算發生錯誤.例如,要查詢在部門10中所有員工的工資合計和獎金合計.由於有些員工的獎金激勵不只一條,在表emp和表emp_bonus之間做連線會導致聚集函式sum算得的值錯誤.
現在,考慮一下下面的返回的在部門10中所有員工的工資和獎金的查詢。表bonus中的type欄位決定獎金額,型別1的獎金為員工工資的10%,型別2為20%,型別3為30%。
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
進行到這,一切正常,然而為了計算獎金總數而跟表emp_bonus做聯接時,錯誤出現了:
select deptno,
sum(sal) as total_sal,
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
)xgroup by deptno
儘管total_bonus所返回的值是正確的,total_sal卻是錯誤的。
total _sal為什麼錯了,因為聯接導致sal列存在重複。考慮下面的查詢。該查詢聯接表emp和emp_bonus
select e.ename,e.sal
from emp e,emp_bonus eb
where e.empno = eb.empno
and e.deptno =10
現在可以很容易的看出total_sal為什麼錯了,因為miller的工資被統計了兩次。
解決方案:當處理聚集與聯接混合操作時,一定要小心。如果聯接產生重複行,可以有兩種方法來避免聚集函式計算錯誤,方法之一,只要在呼叫聚集函式時使用關鍵字distinct,這樣每個值只參與計算一次,另一種方法是,在進行連線前先只想聚集操作(在內聯檢視中),這樣,因為聚集計算已經在連線前完成了,所以就可以避免聚集函式計算錯誤,從而可以完全避免產生此問題。下面列出的解決方案使用了distinct關鍵字,而」討論」部分將討論如何在聯結前使用內聯檢視來只想聚集操作。
select deptno,
sum(distinct sal) as total_sal,
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
)xgroup by deptno
hive內聯接和外聯接
hql很多語句和sql有相似之處,下面用例子快速了解內外聯接的用法 在多表操作的時候,經常會遇到需要的資料,一部分存在a表,一部分存在b表,或者存在更多的表中。而我們可以從這些表的關係進行聯接,下面建立兩個表進行例項演示 首先建立乙個學生資訊表,有id,s name,c name三個屬性 hive ...
資料庫內聯接 左外聯接 右外聯接和全聯接
首先給出兩張表用於之後的舉例 stuno stuname gradeid 1001張三1 1002李四2 1003王五3 1004 西楚霸王 1000 gradeid grade 1一年級 2二年級 3三年級 4四年級 顯示結果為符合條件的多個表間的交集。例 select from grade g,...
聚集索引和非聚集索引
聚集索引和非聚集索引 一 聚集索引和非聚集索引 聚集索引和非聚集索引的根本區別是表記錄的排列順序和與索引的排列順序是否一致,聚集索引表記錄的排列順序與索引的排列順序一致,優點是查詢速度快,因為一旦具有第乙個索引值的紀錄被找到,具有連續索引值的記錄也一定物理的緊跟其後。聚集索引的缺點是對錶進行修改速度...