MYSQL笛卡尔积而不是相关行

时间:2016-02-16 23:42:31

标签: mysql sql database

使用以下数据库和MySQL中的3个表以及以下查询,结果始终是笛卡尔积。相反,我希望得到直接相关的行,如a中的1条记录,bc中的2条记录,结果导致两行,因为外键与{{1}中的许多行相关联{}}和bc中的ONE。

enter image description here

二手查询:

a

最后是查询结果: enter image description here

我做错了什么,我只期望结果,外键约束似乎也是正确的?

这是理想的结果:

enter image description here

1 个答案:

答案 0 :(得分:2)

你没有得到笛卡尔积。你得到的正是你要求的:2个外连接的结果。

你可能还没有意识到,但是你期望2个连接合并transversaly一起只给你2条记录,神奇地知道表B的id应该映射到表C的id。这实际上是可行的方式你想要但是你想的更复杂(参见mysql中的转向以获取更多信息 - 但它只是一个如何做的例子)

相反,我会告诉你你的问题。

  1. 你要求A外连接B.结果是2条记录,因为表B中似乎有2条记录,id_a = 2.中间结果集计数为2.
  2. 你要求外连接C.同样,结果是2条记录,因为表C中似乎也有2条记录,id_a = 2.中间结果集计数为2.
  3. 但是你并没有向mysql询问有关如何组织/加入这两个中间结果集的任何信息。因此,mysql将它们交叉在一起,这可能导致您最初认为它是笛卡尔积,并显示您观察到的最终结果。第1个结果集的总行数= 4,2,第2个结果集的次数为2。

    笛卡尔积将包括所有3个表相互交叉的记录:a次b次c。

    因此,总而言之,您可以通过在C和B之间建立连接标准来“破解”查询以显示您想要的内容。例如:

    SELECT * 
    FROM test.a as tableA
    LEFT JOIN test.b tableB ON tableB.id_a = tableA.id
    LEFT JOIN test.c tableC ON tableC.id_a = tableA.id AND tableC.id = tableB.id
    ;
    

    但实际上这是一个黑客攻击,你可能需要定义一个比技术身份标识更好的标准。