tags:

views:

97

answers:

5

I have three tables; Apartment (apartmentnr, floor, apartmenttype), Floor (floornr, house), House(housenr, adress)

Now, I want to show housenr and adresses of houses that have apartments of all apartmenttypes (1-4), using 'NOT EXISTS'.

Please help me with suggestions on how to do this!

+1  A: 

Ah then you want to use Chris Dates approach, rather than the one made popular Joe Celko? If you are not sure, both approaches are discussed here:

Relational Division by Joe Celko

onedaywhen
+1, excellent link, thanks (but then anything by Celko is bound to be!-)
Alex Martelli
A: 

If I understand your relationships properly you could something like this. Remember you could use alias's for the tables to make it slightly easier to read, I've just kept them in to make it clear what I'm doing.

Select  House.hoursenr, address
inner join Floor on House.housenr = Floor.house
inner join Apartment on Apartment.floor = Floor.floornr
where Apartment.apartmenttype in (1,2,3,4)

I would argue that some of your entity relationships are the wrong way round in your table definitions.

MrEdmundo
If there are multiple appartments in the same house that meet the criteria, the same house will be listed over and over
James Conigliaro
A: 

EDIT: Sorry, misunderstood your question.

Rich.Carpenter
A: 

Given a structure like this:

Houses

ID Address

Floors

ID HouseID

Apartments

Id FloorId ApartmentType

I think this will do the trick:

SELECT H.ID FROM Houses H JOIN Floors F ON H.Id = F.HouseId JOIN Apartments A on F.Id = A.FloorId AND A.ApartmentType = 1 AND H.Id IN 
(SELECT H.ID FROM Houses H JOIN Floors F ON H.Id = F.HouseId JOIN Apartments A on F.Id = A.FloorId AND A.ApartmentType = 2) AND H.Id IN 
(SELECT H.ID FROM Houses H JOIN Floors F ON H.Id = F.HouseId JOIN Apartments A on F.Id = A.FloorId AND A.ApartmentType = 3) AND H.Id IN 
(SELECT H.ID FROM Houses H JOIN Floors F ON H.Id = F.HouseId JOIN Apartments A on F.Id = A.FloorId AND A.ApartmentType = 4)

In English, it means, give me the set of all houses with an apartment of type 1 that are also in the set of houses with an apartment of type 2...and so on.

Chris B. Behrens
+3  A: 

As @onedaywhen hints, not exists is pretty ponderous for this task, and count distinct offers leaner syntax (performance issues are mentioned in the article he points to):

SELECT House.adress
FROM House
JOIN Floor ON (House.housenr=Floor.house)
JOIN Apartment ON (Floor.floornr=Apartment.floor)
GROUP BY House.housenr
HAVING COUNT(DISTINCT Apartment.apartmenttype)=4

which essentially says "show adress [[sic]] of houses with 4 different types of apartments". Only good reason to force the use of not exists would be, as others hinted, homework...

Alex Martelli
Oooh...nice one. Didn't think of that.
Chris B. Behrens
I didn't want to do that work after the comment was posted suggesting this might be homework (that's my excuse anyhow).
onedaywhen
@Chris, thanks! @onedaywhen, if it was homework with the specific instruction to use NOT EXISTS this won't help @Anna with it, but I do hope it can be instructive in a more general way.
Alex Martelli