views:

198

answers:

3

Here is a table

CarID| Attribute    | Value
1   | Color     | Red
2   | Color     | Blue 
3   | Color     | Red 
1   | Type      | Coupe 
2   | Type      | Hatch Back 
3   | Type      | Coupe
3   | Make      | Honda
2   | Make      | Toyota
1   | Make      | Ford

Now I would like to run a filter Like Select * From Cars WHERE (Attribute = Color AND Value = Red) AND (Attribute = Make AND Value = Honda).... and Hope to get the CarID as 3 !

This is simple case of Intersection of 2 queries but I don't know how to get it done in a single query.

Any help appriciated.

+1  A: 
select
      carid,
      count(*) matchedItems
   from
      YourTable
   where
        ( Attribute = 'Color' and Value = 'Red' )
     OR ( Attribute = 'Make' and Value = 'Honda' )
   group by 
      carid 
   having
      matchedItems = 2;

you may have to change the having to...

 having count(*) = 2
DRapp
Hey dude !Awesome it worked ! Thanks ! Any suggestion of reading I can do to better my Mysql skills ?
Jeebus
+1 note: mysql docs from 4.1 to 5.1 say that you can use column alias in GROUP BY, ORDER BY, or HAVING clauses
Unreason
not specifically, but best thing is to KNOW YOUR DATA and the relationships between them. Also, many people prefer to do JOINs on queries (matching elements on both sides) instead of multiple "FROM" tables and using the "WHERE" clause to identify the relationship. I prefer to only use things like left joins (one-sided). Additionally, the keyword STRAIGHT_JOIN can help when you know your data and the critical path to the primary criteria of extraction... I've done before against 15+ million record tables and get great results against 16+ lookup tables linked to the master table.
DRapp
+1  A: 

The most straightforward solution would be to simulate a separate table for each attribute with sub queries (although it might not be the most efficient):

SELECT Colors.CarID FROM
    ( SELECT CarID, Value FROM Cars WHERE Attribute = 'Color' ) Colors,
    ( SELECT CarID, Value FROM Cars WHERE Attribute = 'Make' ) Makes
    WHERE Colors.CarID = Makes.CarID AND Colors.Value = 'Red' AND
        Makes.Value = 'Honda';
Mike Pelley
you forgot to quote the strings in comparisons
Unreason
Good point - fixed! And the colors have improved too ;o)
Mike Pelley
A: 

Here is another variant of the query

SELECT carid
FROM AnotherUnknownTableName t INNER JOIN  
     AnotherUnknownTableName t2 ON t.carid = t2.carid AND 
                                   t.Attribute = 'Color' AND 
                                   t2.Attribute = 'Make'
WHERE 
     t.Value = 'Red' AND t2.Value = 'Honda'

Having an index on (carid, Attribute) will do wonders.

Unreason