I am working on an EAV storage system for storing schemaless meta data about an object, and am now working on a way to have it searchable, but have most of the processing done by the Database Server.
The table of the EAV is:
`entityID` - INT(11)
`entity` - VARCHAR(128)
`attribute` - VARCHAR(128)
`value` - BLOB
This is my statement:
SELECT
`entity`,
(CASE WHEN `attribute` = 'bob' THEN `value` ELSE NULL END) `bob`,
(CASE WHEN `attribute` = 'dean' THEN `value` ELSE NULL END) `dean`
FROM `eav`
which returns a nice set of rows (as expected) like this:
+----------+------+------+
| entity | bob | dean |
+----------+------+------+
| testEnt | foo | NULL | // attribute = bob
+----------+------+------+
| testEnt | NULL | NULL | // another test attribute
+----------+------+------+
| testEnt | NULL | NULL | // another test attribute
+----------+------+------+
| testEnt2 | foo | NULL | // attribute = bob
+----------+------+------+
| testEnt2 | NULL | foo | // attribute = dean
+----------+------+------+
but when I attach GROUP BY (Entity), the result turns into this:
+----------+------+------+
| entity | bob | dean |
+----------+------+------+
| testEnt | foo | NULL |
+----------+------+------+
| testEnt2 | foo | NULL |
+----------+------+------+
so using the HAVING syntax after that stops working. Is there a way so that the result returned is:
+----------+------+------+
| entity | bob | dean |
+----------+------+------+
| testEnt | foo | NULL |
+----------+------+------+
| testEnt2 | foo | foo |
+----------+------+------+
Apply an aggregate function with the
CASEand theGROUP BY. Since the values are strings you can use either aMAX()orMIN()to return the result:See SQL Fiddle with Demo
In the event, you have an unknown number of
attributevalues to return, you can use a prepared statement to get the result:See SQL Fiddle with Demo
The result for both will be: