1

我想知道将 LEFT JOIN 转换为表/矩阵的好解决方案。

例如,给定这个模式:

对象
   id(整数)
   名称(字符串)

属性
   id(整数)
   object_id (整数)
   名称(字符串)
   值(字符串)

这些价值观:

1、球
2、盒子

1,1,颜色,红色
2,1,形状,球体
3,1,材料,橡胶
4,2,颜色,棕色
5,2,形状,立方体

我想得到这个:

object_id | 对象名 | 颜色 | 形状 | 材料

1 | 球 | 红色 | 球体 | 橡胶
2 | 盒子| 棕色 | 立方体 | 无效的

理想情况下,这将是每个对象的属性数量未知,并且对于 MySQL 不使用存储过程。

4

4 回答 4

2

RDBMS的作用是它们的目的是存储和呈现你已经拥有的东西。从未打算动态创建列。

这是应该在要呈现数据的客户端上处理的情况。

不考虑应该如何使用 RDBMS,您仍然找不到简单的方法来做到这一点。如果您希望列列表是动态的,则尤其如此。您可以构建动态 SQL 查询并执行该查询,但无法编写标准 SQL 查询并获得该结果(因为您总是显式指定所有列,使用 bar *,但在这种情况下不能利用您的优势.)

于 2009-07-20T12:40:30.247 回答
1

如果不使用动态查询,您将无法做到这一点SQL

任何SQL处理的集合都假定有固定数量的列,具有固定的名称。

否则会导致很多事情SQL只是没有设计来处理。

就像,想象一下在您要求的查询上创建的视图(如果可能的话):

SELECT  object_id, colour
FROM    myquery

这个视图是否编译取决于查询的结果,这会给你运行时错误(很难处理)而不是空的结果集(这很容易处理)。

您在这里基本上是在谈论结果演示,而这些事情通常是在客户端完成的。

如果您的attribute_names表包含所有可能的属性名称,则可以执行以下操作:

SELECT  o.name, an.name, a.value
FROM    objects o
CROSS JOIN
        attribute_names an
LEFT JOIN
        attributes a
ON      a.object = o.id
        AND a.name = an.name

,它将包含object_id / attribute_name具有相应值的所有可能对,您可以在客户端使用它来更轻松地填充矩阵。

于 2009-07-20T12:38:59.997 回答
0

嗯,这可能是您缺少 2 个逻辑步骤来实现这一点。

您需要的是一个 AttributeTypes 表和一个 AttributeValues 表。

objects
   id (integer)
   name (string)

attribute_types
   id (integer)
   name (string)
   description (string)
   enabled (bit)

attribute_values
   id (integer)
   attribute_type_id (integer)
   value (string)
   enabled (bit)

attributes
   id (integer)
   object_id (integer)
   attribute_type_id (integer)
   attribute_value_id (integer)

所以一个对象可以有属性,这些属性由attribute_type_id 和attribute_value_id 指定。

然后,这允许您拥有一个具有多个属性的对象..

例如

object 
-> 1, ball

attribute_types
-> 10, Colour, null, enabled
-> 20, Shape, null, enabled
-> 30, Material, null, enabled

attribute_values 
-> 100, 10, blue, enabled
-> 200, 10, red, enabled
-> 300, 10, green, enabled

-> 400, 20, round, enabled
-> 500, 20, square, enabled
-> 600, 20, triangle, enabled

所以一个属性看起来像:

attributes
-> 1000, 1, 10, 100 // this item has a color and it is blue
-> 1001, 1, 20, 400 // this item has a shape and it is round
-> 1002, 1, 10, 200 // this item has a color and it is red

所以现在对象可以有多个属性,这些属性在不同的表中指定它们的值。现在重要的问题是如何查询这个?您可能必须将查询拆分为多个部分,具体取决于您的 sql 的强度。

@attribute_type_id = select Id from attribute_types where name = 'Color' // 10

select * from objects 
inner join attributes on objects.id = attributes.object_id
inner join attribute_values on objects.attribute_value_id = attribute_values.id
where attribute_type_id = @attribute_type_id
and attribute_values.value= 'blue'

有了它,您应该带回每个具有颜色属性类型和蓝色属性值的对象。

My Sql 不是那么强大,但如果您想一次搜索多个属性,您应该能够执行多个子句。在我看来,attributes table 中的 attribute_type_id 没有加入 attribute_type 表,但它可以方便在 1 次命中中进行查询,虽然我拥有它,但性能明智,因此它可以通过不必加入来加速查询表,但根据所有内容的大小,差异可能可以忽略不计。

注意:我通常使用 msssql 而不是 mysql,所以如果数据库类型不匹配,这就是原因。

于 2011-03-26T08:11:55.537 回答
0

假设结果表被称为合并,这将解决您的问题,尽管我说的架构更好。

insert into merged (object_id, object_name) select id, name from objects;
update merged m inner join attributes a on a.object_id = m.object_id and a.name = 'colour' set m.colour = a.value;
update merged m inner join attributes a on a.object_id = m.object_id and a.name = 'material' set m.material = a.value;
update merged m inner join attributes a on a.object_id = m.object_id and a.name = 'shape' set m.shape = a.value;
于 2009-07-20T12:46:14.007 回答