2014-10-27 27 views
1

我正在編寫一個查詢來從僱員結婚但沒有孩子的數據庫中選擇員工姓名。SQL - 排除元組

我有兩個不同的表:員工及受養人

員工都有以下字段

fname, lname, ssn 

和家屬有以下領域

essn, dependents_name, relationship 

Dependents.essn是一個FK引用Employee.ssn

Some Employee.ssn have m部門中有多個元組,每個元組都有一個不同的relationship狀態(配偶,兒子,女兒),描述員工所屬的依賴類型。

我正在尋找一個基於ssn - > essn關係來選擇那些僱員的查詢,這些關係具有spouse而非sondaughter的關係。

到目前爲止,這是我已經試過:

select e.fname, d.relationship 
from (employee e left outer join dependents d 
on e.ssn = d.essn) 
where d.relationship = 'spouse' 

它返回員工的元組與spouse價值,而且還與sondaughter值。

如何過濾我的表格以僅包含spouse值的員工?

回答

0

可以使用NOT EXISTS條款

select e.fname, d.essn, d.relationship 
from employee e 
join dependents d 
on e.ssn = d.essn 
and d.relationship = 'spouse' 
and not exists (select 1 from dependents d1 
       where d1.essn= e.ssn 
       and d1.relationship <> 'spouse' 
) 
+0

嵌套語句中'<>'的含義是什麼?另外,'選擇1'? – Delfino 2014-10-27 02:46:40

+0

<>表示不等於,其次是核心子查詢,如果除了配偶以外的其他同一僱員還有其他關係,則返回1,因此不存在將消除這樣的行。這裏是sql小提琴http://www.sqlfiddle.com/#!3/d36cf/1 – radar 2014-10-27 02:49:15

+0

謝謝!像魅力一樣工作,但我使用'select d1.essn'來代替。 – Delfino 2014-10-27 03:16:56

0

你可以用聚集做到這一點,一個having條款:

select e.fname 
from employee e left outer join 
    dependents d 
    on e.ssn = d.essn 
group by e.fname 
having sum(case when d.relationship = 'spouse' then 1 else 0 end) > 0 and 
     sum(case when d.relationship in ('son', 'daughter') then 1 else 0 end) = 0; 
1

這裏的另一種方式與公共表表達式和countpartition

with cte as (
    select e.fname, 
    d.relationship, 
    count(d.relationship) over (partition by e.ssn) cnt 
    from employee e 
    join dependents d on e.ssn = d.essn 
) 
select fname, relationship 
from cte 
where cnt = 1 and relationship = 'spouse' 

BTW,沒有必要的OUTER JOIN - 你WHERE標準取消它,因爲你需要一個配偶存在。

+0

+1,即使將新關係添加到模式並且對分區進行計數也適用於此情況。 – radar 2014-10-27 03:08:50

+0

我剛剛開始學習SQL,所以我不熟悉'over'和'partition' – Delfino 2014-10-27 03:20:29