2013-08-23 22 views
0

我们使用的是实体 - 属性 - 值模式来存储在我们的项目中的对象。它基本上是这样的:排序超过两列的实体属性值架构

实体 - 所有条目的原型的虚拟存储设备(汽车,房屋等)

进入(单一实体对象的表示)

  • ID
  • entity_id
  • ...

参数(所有实体属性的颜色,名称,品牌等)

  • ID
  • ...

(为一个条目和参数单个值)

  • entry_id(外键entry.id)
  • parameter_id(外键parameter.id)
  • 值(实际值)

这些表代表存储在MySQL数据库动态表。

该方案的唯一问题是对2个(或更多)参数进行排序。例如,通过manufacturing_year DESC和品牌ASC对所有汽车进行分类。

我们需要的最终结果是进入IDS的排序列表。

对于这些对象:

实体

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

进入

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

参数

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

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 
---------------------------------------------- 

这些条目由给定条件的正确顺序是768,16 3,1,2

+0

你试过'... ORDER BY年份desc,品牌asc'吗? – fancyPants

+0

@fancyPants它比clausule的单一订单复杂得多。年份和品牌实际上并不是表中的列,但它们存储在参数表中。 – user1894369

+0

您的查询(经过一些调整以使其工作)只产生一行。调整你的样本数据。更重要的是,不要让那些试图帮助你的人变得更加困难。这只是糟透了,你知道吗? – fancyPants

回答

2

您可以加入参数表多次,你必须参数进行排序,以参数的ID作为加入条件,使你得到一个简单的行集值列进行分类。

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 
+0

您的解决方案比以前更快。根据我们的数据(约700k行的值),它非常快。非常感谢! – user1894369

2

因此,回顾一下,你有台这样的事情...

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'); 

......从中可以得到的结果是这样的......

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 | 
+--------+--------------+------+ 

...所以什么问题来着?

(祈求怜悯穷人数据类型)

+0

别担心,我们为不同的值类型分隔了列。这正是我想要的。谢谢。 – user1894369