2014-10-09 34 views
1

我試圖更好地理解關係代數,並且在解決以下類型的問題時遇到了問題:如何查找所有A的子類別B都與同一列C相關的列?

假設有一列A(Department),一列B(Employees)和一列C(經理)。我怎樣才能找到所有員工都只有一名經理的部門?提供一個例子如下:

Department | Employees | Managers 
-------------+-------------+---------- 
    A   | John  | Bob 
    A   | Sue  | Sam 
    B   | Jim  | Don 
    B   | Alex  | Don 
    C   | Jason  | Xie 
    C   | Greg  | Xie 

在該表中,因此我應該得到的是含有部門B和C的所有元組,因爲他們所有的員工都是由同一人(唐和謝分別)管理。然而,A部門不會因爲員工有多個經理而被退回。

任何幫助或指針,將不勝感激。

回答

0

這類問題通常要求進行自連接。

將Department上的關係加入到自身上,然後過濾掉Managers相等的元組會產生所有不需要的元組,這些元組我們可以從原始關係中減去。

以下是我會做:

T - \pi_{T.Department, T.Employee, T.Manager} \left(\sigma_{T.Manager \neq T2.Manager \land T.Department = T2.Department}\left(\rho(T, T_2) \times T\right) \right)

首先我們做表T的副本,並將其命名爲T2,然後採取T和T2的積。從結果我們選擇所有的行,其中T1.Manager/= T2.Manager但T1.Department = T2.Department,產生我們這些元組:

T1.Department | T1.Employees| T1.Managers | T2.Managers | T2.Employees | T2.Department 
--------------+-------------+-------------+-------------+--------------+-------------- 
    A   | John  | Bob  | Sam   | Sue   | A 
    A   | Sue  | Sam  | Bob   | John   | A 

部門A和B是不存在的,因爲他們的T1。管理器始終等於T2.Manager。

然後我們只是減去這個結果的原始設置得到答案。

0

如果您的RDBMS支持公共表表達式:

with C as (
    select department, manager, count(*) as cnt 
    from A 
    group by department, manager 
), 
B as (
    select department, count(*) as cnt 
    from A group by department 
) 
select A.* 
from A 
join C on A.department = C.department 
join B on A.department = B.department 
where B.cnt = C.cnt; 
+1

謝謝,但我不能使用聚合函數,如計數(因此不能組)。我試圖用關係代數來解決這個問題。 – n0shadow 2014-10-09 14:21:46

相關問題