Reputation: 1009
I'm writing a query to select employee names from a database where the employees are married but have no children.
I have two different tables: Employee and Dependents
Employee has the following fields
fname, lname, ssn
And Dependents have the following fields
essn, dependents_name, relationship
Dependents.essn is a FK that references Employee.ssn
Some Employee.ssn have multiple tuples in Department, each with a different relationship
status (spouse, son, daughter), describing the type of dependent that employee has.
I'm looking to write a query that selects those employees, based on the ssn -> essn relationship, that have the relationship spouse
but not the relationships son
or daughter
.
So far, this is what I've tried:
select e.fname, d.relationship
from (employee e left outer join dependents d
on e.ssn = d.essn)
where d.relationship = 'spouse'
It returns the tuples of employees with the spouse
value, but also with the son
and daughter
value.
How can I filter my tables to include only those employees with the spouse
value?
Upvotes: 1
Views: 698
Reputation: 13425
you can use NOT EXISTS
clause
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'
)
Upvotes: 0
Reputation: 62861
Here's another way with a common table expression and count
with partition
:
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, no need for an OUTER JOIN
-- your WHERE
criteria negates it since you require a spouse to exist.
Upvotes: 1
Reputation: 1270713
You can do this with aggregation and a having
clause:
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;
Upvotes: 0