質問

We are using a entity-attribute-value schema to store objects in our project. It's basically like this:

entity- dummy storage of all entries prototypes (car, house etc.)

entry (representation of single entity object)

  • id
  • entity_id
  • ...

parameter (all entity attributes color, name, brand etc.)

  • id
  • name

value (single value for one entry and parameter)

  • id
  • entry_id (foreign key to entry.id)
  • parameter_id (foreign key to parameter.id)
  • value (actual value)

These tables represent dynamic tables stored in MySQL database.

The only problem with this scheme is sorting over 2 (or more) parameters. For example sort all cars by manufacturing_year DESC and brand ASC.

The final result we need is the sorted list of entry ids.

For these objects:

entity

id | name
------------------------------
1  | Car
------------------------------

entry

id| entity_id
-------------
1 | 1
-------------
2 | 1
-------------
3 | 1
-------------

parameter

id| entity_id | name
-----------------------
1 | 1         | Brand
-----------------------
2 | 1         | Year 
-----------------------

value

id | entry_id | parameter_id | value 
----------------------------------------------
1  | 1        | 1            | Tatra
----------------------------------------------
2  | 1        | 2            | 2005
----------------------------------------------
3  | 2        | 1            | Aston Martin
----------------------------------------------
4  | 2        | 2            | 1999
----------------------------------------------
5  | 3        | 1            | Man
----------------------------------------------
6  | 3        | 2            | 2005
----------------------------------------------

The correct order of these entries by given criteria shoud be 3, 1, 2.

役に立ちましたか?

解決

You can join parameter table as many times as you have parameters to sort on, with parameter id's as join conditions, so you get a simple rowset with values as columns for sorting.

SELECT entry.id as entry_id, 
       v_brand.value as brand,
       v_year.value as year 
FROM entity
  JOIN entry 
    ON entity.id = entry.entity_id
  JOIN value v_brand 
    ON v_brand.parameter_id = 1 
    AND v_brand.entry_id = entry.id
  JOIN value v_year 
    ON v_year.parameter_id = 2 
    AND v_year.entry_id = entry.id
WHERE entity.name = 'Car'
ORDER BY year DESC, brand ASC

他のヒント

So, to recap, you have table something like this...

DROP TABLE IF EXISTS eav_hell;

CREATE TABLE eav_hell
(entity INT NOT NULL
,attribute VARCHAR(12) NOT NULL
,value VARCHAR(12)
);

INSERT INTO eav_hell VALUES
(1,'Brand','Tatra'),
(1,'Year','2005'),
(2,'Brand','Aston Martin'),
(2,'Year','1999'),
(3,'Brand','Man'),
(3,'Year','2005');

...from which you can obtain a result something like this...

SELECT entity
     , MAX(CASE WHEN attribute = 'Brand' THEN value END) Brand
     , MAX(CASE WHEN attribute = 'Year' THEN value END) Year
  FROM eav_hell
 GROUP
    BY entity;   

+--------+--------------+------+
| entity | Brand        | Year |
+--------+--------------+------+
|      1 | Tatra        | 2005 |
|      2 | Aston Martin | 1999 |
|      3 | Man          | 2005 |
+--------+--------------+------+

...so what was the problem again?

(and pray pity the poor data types)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top