MS Access sql - 与AND的多个连接提供笛卡尔积?

时间:2016-06-08 13:07:36

标签: sql ms-access join cartesian-product

-- MS ACCESS sql to present row based data as column based
-- Gives too many rows probably Cartesian product. If I have 5 toys with one color and one weight each I expect 5 rows, but get more
SELECT
t.ToyId 
,t.ToyName
,p1.TextValue as 'Color'
,p2.FloatValue as 'Weight'
FROM (my_toys t
LEFT OUTER JOIN properties p1 ON (t.ToyId = p1.ToyId)  AND (p1.propertyId='Color'))) 
LEFT OUTER JOIN properties p2 ON (t.ToyId = p2.ToyId)  AND (p2.propertyId='Weight'))  

我正在MS Access SQL中演示未来的MySQL数据库。我有一个玩具表,我有一个颜色,重量,长度等属性表。属性表中的每一行代表一个玩具的一个属性,所以它是一个基于行的存储。属性表中的行示例可以是:

  • 玩具= 1; ProperyType = '颜色'; TextValue = '蓝';的floatValue = NULL;
  • 玩具= 1; ProperyType ='Weight'TextValue = null;的floatValue = 42;
  • 玩具= 1; ProperyType ='长度'TextValue = null;的floatValue = 123;
  • 玩具= 2; ProperyType = '颜色'; TextValue = '红色';的floatValue = NULL;

当我设法获得正确的语法时,上面的SQL不会为每个玩具提供一行颜色和重量的列,而是笛卡尔积,至少有太多行。这个sql问题的目的是将基于行的数据模型转换为基于列的数据,以提高人类的可读性。

我已经为MySQL中的视图制作了类似的构造,但是我无法理解我在MS Access SQL代码中犯了什么错误。任何人都可以帮助我吗?

(请注意我的实际项目不适用于玩具,因此代码可能包含一些输入错误)

2 个答案:

答案 0 :(得分:0)

左连接上的复合条件可能导致()访问添加的操作顺序出现问题......

SELECT
t.ToyId 
,t.ToyName
,p1.TextValue as 'Color'
,p2.FloatValue as 'Weight'
FROM my_toys t
LEFT OUTER JOIN (Select * from properties where  p1.propertyId='Color') p1 
   ON t.ToyId = p1.ToyId
LEFT OUTER JOIN (Select * from properties where p2.propertyId='Weight') p2 
   ON t.ToyId = p2.ToyId  

答案 1 :(得分:0)

感谢xQbert,我尝试了你的解决方案。当我仍然有太多行时,我真的再次查看了我的数据表,结果我得到了另一个标识符"玩具",让我们称之为所有者。所以每个ToyId实际上有多个玩具,所以这一直是我的错误。但是,如果我没有得到你的解决方案,我就会把Access变为无法使用!

还要感谢所有评论,从这个问题我学到了一些东西。

  1. 我现在可以在MS Access SQL中加入和加入subquerys了!
  2. 在向你们提问之前,我将总是做一个简单的准系统示例。然后我可以找到我自己的愚蠢错误,并且你有工作代码和一个示例数据库来测试。
  3. 我不应该这么多不信任MS Access SQL!在这个例子中,我首先想到的是由于语言的限制,无法与AND进行多次连接。