tags:

views:

10

answers:

1

I have a listings database. I also have a listings_attributes database that looks like this:

id | listing_id | attribute_id

Basically the listings_attributes table stores the attributes that are assigned to a certain listing.

I am wanting to filter listings depending on what attributes they have.

An example would be I want to find all the listings with an attribute_id of 1. That's easy.

SELECT l.id FROM listings AS l 
    LEFT JOIN listings_attributes AS la ON l.id = la.listing_id 
    WHERE la.attribute_id = 1
    GROUP BY l.id

What my problem is how do I pull out listings that have a an attribute_id of 1 and 2. If there are listings with an attribute_id of 1 but doesn't have an attribute_id of 2, I don't want these to be pulled out of the database.

However, if there are listings with an attribute_id of 1, 2 and 3 I would like these to be pulled out of the database.

Here is my SQL that I was playing with but the "OR" between attribute_id's doesn't work and neither does "AND".

SELECT l.id FROM listings AS l 
    LEFT JOIN listings_attributes AS la ON l.id = la.listing_id 
    WHERE (la.attribute_id = 1 OR la.attribute_id = 2) 
    GROUP BY l.id

What code would I need to make it work the way I've explained above?

+1  A: 

When looking for multiple attributes, you need to use a GROUP BY with an OR to make sure that the attributes both exist in the listings_attributes table, like you already have. Then you add a HAVING clause to make sure that more than one row matches. Like so:

SELECT l.id FROM listings AS l  
  LEFT JOIN listings_attributes AS la ON l.id = la.listing_id 
  WHERE (la.attribute_id = 1 OR la.attribute_id = 2) 
  GROUP BY l.id HAVING COUNT(*) = 2
Chris Henry
Thanks Chris! Is there anyway to make the HAVING COUNT(*) = 2 more specific? I actually have multiple LEFT JOINS in my code and I think it might be getting mixed up.
Ben Sinclair
Actually I think I just some wrong testing. Looks like it's working :) Thanks for your help!
Ben Sinclair