I have the following table:
Guy Table:
+------+----------+------+
| guy | attribute| value|
+------+----------+------+
| John | age | 12 |
| John | dollars | 15 |
| John | candies | 3 |
| Bob | age | 15 |
| Bob | dollars | 20 |
| Bob | candies | 6 |
+------+----------+------+
How can I get all the guys that match any kind of condition in its attributes and values?
Basically I want to be able to search guys and its attributes using all kinds of conditions like gt, lt, ge, le, eq, ne, between, etc.. and also be able to group these conditions by "ands" and "ors".
For example, lets say I want to get the guys that have more than 16 dollars or have less than 5 candies, so I would try something like this:
select guy,attribute,value from guy group by guy having (attribute = 'dollars' and value > 16) or (attribute = 'candies' and value < 5);
I would expect both John and Bob to be returned, but an empty set is returned instead (no matches).
and that is just a simple query, the queries could get as complicated as this one
//get guys that have more than 2 candies and also have more than 16 dollars but no matter what, don't forget to get the guys which age is exactly 12
select guy,attribute,value from guy group by guy having ((attribute = 'candies' and value > 2) and (attribute = 'dollars' and value > 16)) or (attribute = 'age' and value = 12);
this last query should also return both John and Bob, but only John is returned
Here is the code to create the table and add the rows:
create table guy(guy varchar(255), attribute varchar(255), value int);
insert into guy values('John', 'age', 12),('John', 'dollars', 15),('John', 'candies', 3),('Bob', 'age', 15),('Bob', 'dollars', 20),('Bob', 'candies', 6);
Have in mind that I could later add more more guys and more attributes, but all guys will always have the same number of attributes, for example, if I were to add 'Mario', I would do the following inserts:
insert into guy values('Mario', 'age', 18),('Mario', 'dollars', 31),('Mario', 'candies', 10);
and if I were to add the attribute 'apples' I would do the following inserts:
insert into guy values('John', 'apples', 3), ('Bob', 'apples', 5), ('Mario', 'apples' 0);
I hope I made myself understandable, thank you for all your time :)
Note: the guy table is a view and is the result of joining 3 tables, so don't worry about the database not been normalized, also please don't tell me that the queries are wrong (cause I already know that), instead, better tell me what should I change in them.
Edit (Oct 18 2011, 10:08 AM):
Maybe If there were a way to put all of each guys attributes in one row?, like this:
+------+-----------+-------+------+------------+--------+------+------------+--------+
| guy | attribute | value | guy | attribute | value | guy | attribute | value |
+------+-----------+-------+------+------------+--------+------+------------+--------+
| John | age | 12 | John | dollars | 15 | John | candies | 3 |
| Bob | age | 15 | Bob | dollars | 20 | Bob | candies | 6 |
+------+-----------+-------+------+------------+--------+------+------------+--------+