2009-11-09 155 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,然後擺脫代理鍵。