2009-11-09 157 views
1

我有它定义了哪些东西另一个表可以有,例如表:复杂SELECT查询

CREATE TABLE `objects` (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    `name` VARCHAR(50) NOT NULL 
); 

INSERT INTO `objects` (`name`) VALUES ('Test'); 
INSERT INTO `objects` (`name`) VALUES ('Test 2'); 

CREATE TABLE `properties` (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    `name` VARCHAR(50) NOT NULL 
); 

INSERT INTO `properties` (`name`) VALUES ('colour'); 
INSERT INTO `properties` (`name`) VALUES ('size'); 

CREATE TABLE `objects_properties` (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    `object_id` INT UNSIGNED NOT NULL, 
    `property_id` INT UNSIGNED NOT NULL, 
    `value` VARCHAR(50) NOT NULL, 
    FOREIGN KEY (`object_id`) 
    REFERENCES `objects` (`id`), 
    FOREIGN KEY (`property_id`) 
    REFERENCES `properties` (`id`) 
); 

INSERT INTO `objects_properties` (`object_id`, `property_id`, `value`) VALUES 1, 1, 'red'); 
INSERT INTO `objects_properties` (`object_id`, `property_id`, `value`) VALUES 1, 2, 'small'); 
INSERT INTO `objects_properties` (`object_id`, `property_id`, `value`) VALUES 2, 1, 'blue'); 
INSERT INTO `objects_properties` (`object_id`, `property_id`, `value`) VALUES 2, 2, 'large'); 

希望这是有道理的。基本上,而不是在对象表中有颜色,大小等列,我有两个其他表,其中一个定义任何对象可以具有的属性,另一个表将对象链接到一些或所有这些属性。

我的问题是,如果有一些方法来获取这些信息是这样的:

 
+--------+------------+------------+ 
| object | colour  | size  | 
+--------+------------+------------+ 
| Test | red  | small  | 
| Test 2 | blue  | large  | 
+--------+------------+------------+ 

所以你可以看到的列标题实际上行值。我不确定是否可能,或者相比于做一些单独的查询并将所有内容整合到PHP中的代价是多么昂贵。

回答

4
SELECT o.name, c.colour, s.size 
FROM objects o 
LEFT JOIN (SELECT op.object_id, op.value colour 
     FROM objects_properties op 
     join properties p on op.property_id = p.id and p.name = 'colour') c 
ON o.id = c.object_id 
LEFT JOIN (SELECT op.object_id, op.value size 
     FROM objects_properties op 
     join properties p on op.property_id = p.id and p.name = 'size') s 
ON o.id = s.object_id 
+0

第三个别名应该是s。 – recursive 2009-11-09 14:17:30

+0

固定,谢谢。 – manji 2009-11-09 15:09:01

+0

我认为这不太对。 'c.colour'总是'color',因为它指的是属性名'p.name',但是我可以看到如何调整它以显示op.value' – Rob 2009-11-10 14:12:55

1

这里的关键字是“数据透视表”“crosstab”(但是“数据透视表”也位于该方向)并且不,MySQL不能直接执行此操作。您可以创建一个查询来选择它,但是您必须在查询中自己明确定义列。没有从另一个表中获取列。其他RDBMS可能有这方面的功能。

0

枢轴(或类似的东西)可能是有用的。在MS SQL Server中,您可以使用它,但是转换表的值必须是常量,或者您可以使用存储过程来计算它。

Here you can find more info

祝您有美好的一天!

0
SELECT o.*, 
     (
     SELECT * 
     FROM object_properties op 
     WHERE op.object_id = o.object_id 
       AND op.property_id = $prop_color_id 
     ) AS color, 
     (
     SELECT * 
     FROM object_properties op 
     WHERE op.object_id = o.object_id 
       AND op.property_id = $prop_size_id 
     ) AS size 
FROM objects o 

替代$prop_color_id$prop_size_idcolorsize财产id的。

为使此查询有效率,请在object_properties中输入(object_id, property_id) a PRIMARY KEY,然后摆脱代理键。