我有一个表,用于定义另一个表可以拥有的内容,例如:
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中相比,它是否可能或成本是多少。
答案 0 :(得分: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
答案 1 :(得分:1)
这里的关键字是“数据透视表”“交叉表”(但是“数据透视表”也在那个方向)而不是,MySQL不能直接执行此操作。您可以创建一个将选择此项的查询,但您必须在查询中自己显式定义列。无法从另一个表中获取列。其他RDBMS可能具备此功能。
答案 2 :(得分:0)
pivot (或类似的东西)可能很有用。在MS SQL Server中,您可以使用它但是,旋转表的值必须是常量,或者您可以使用存储过程来计算它。
度过美好的一天!
答案 3 :(得分: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_id
属性color
代替size
和id
。
要使此查询有效,请在(object_id, property_id)
中PRIMARY KEY
object_properties
并删除代理密钥。