2017-08-14 106 views
0

我发现很多基于第三个ID的合并两个表的类似帖子,但是我似乎无法解决逻辑问题。mysql根据第三个ID创建两个表的视图

给 三个表

tableA

| uuid | ttl | ord | 
----------------------- 
| alpha| Alp |  1| 
| beta| Bet |  2| 
| gamma| Gam |  3| 

tableB

| uuid | ttl | ord | tab_A_ref 
-------------------------------- 
| joe | Jo |  1| alpha 
| mike | Mi |  2| beta 
| peter| Pe |  3| alpha 
| alan | Pe |  4| beta 
| tom | Pe |  5| gamma 

tableC

| uuid | ttl | ord | tab_A_ref 
-------------------------------- 
| jane | Ja |  1| alpha 
| marg | Ma |  2| beta 
| phobe | Ph |  3| alpha 
| anon | An |  4| beta 
| toni | To |  5| gamma 

我期待用一个基本的连接创建一个视图 myView其中tab_A_ref = alpha or beta

| uuid | ttl | ord | tab_A_ref 
| joe | Jo |  1| alpha 
| peter | Pe |  3| alpha 
| jane | Ja |  1| alpha 
| phobe | Ph |  3| alpha 
| mike | Mi |  2| beta 
| alan | Pe |  4| beta 
| marg | Ma |  2| beta 
| anon | An |  4| beta 

SELECT 
    tableB.uuid, tableB.ttl, tableB.ord, tableB.tab_A_ref 
    FROM tableB 
    INNER JOIN tableA on tableB.tab_A_ref = tableA.uuid 

我延长了逻辑合并两个

SELECT 
     tableB.uuid, tableB.ttl, tableB.ord, tableB.tab_A_ref, 
     tableC.uuid, tableC.ttl, tableC.ord, tableC.tab_A_ref, 
FROM 
     tableB INNER JOIN tableA on tableB.tab_A_ref = tableA.uuid, 
     tableC INNER JOIN tableA on tableC.tab_A_ref = tableA.uuid 

但产生错误not unique table/alias: tableA

从其他帖子看来,我应该有一个嵌套bracketed JOIN,尝试了许多组合都失败。那么如何格式化第二个JOIN

+0

您正在使用'JOIN'不正确,最后一行只是需要'INNER JOIN tableC ON ...'而没有预先输入逗号 – RealCheeseLord

+0

这个数据结构看起来非常不规范。为什么表B和C具有相同的字段?他们当然应该是一张桌子?如果它们代表相同但具有略微不同属性的内容(例如,似乎有男性名字和女性名字),那么只需额外添加一列就可以更好地进行区分。 – ADyson

+0

如果所有tableB和tableC行都在tableB中,那么查询(包括对alpha/beta的限制)将简单地为'SELECT tableB.uuid,tableB.ttl,tableB.ord,tableB.tab_A_ref FROM tableB INNER JOIN tableA on tableB.tab_A_ref = tableA.uuid WHERE tableA.uuid in('alpha','beta')' – ADyson

回答

2

所有表(临时,子查询,物理或其他)必须在查询中唯一命名。

否则,数据库引擎不知道您指的是哪个数据源。

您的原始:

SELECT 
     tableB.uuid, tableB.ttl, tableB.ord, tableB.tab_A_ref, 
     tableC.uuid, tableC.ttl, tableC.ord, tableC.tab_A_ref, 
FROM 
     tableB INNER JOIN tableA on tableB.tab_A_ref = tableA.uuid, 
     tableC INNER JOIN tableA on tableC.tab_A_ref = tableA.uuid 

在上面,如何查询引擎知道用哪个tableA?你已经宣布了两次。请记住,您正在应用过滤器(ON tableB.tab_A_ref = tableA.uuid) - 因此您有两个结果集(一个来自第一个加入,另一个来自第二个加入),它们都被称为tableA

简单地说,使用别名(AS)来唯一地引用的所有表(接合或以其它方式):

SELECT 
     tableB.uuid, tableB.ttl, tableB.ord, tableB.tab_A_ref, 
     tableC.uuid, tableC.ttl, tableC.ord, tableC.tab_A_ref, 
FROM 
     tableB INNER JOIN tableA AS a_ref ON tableB.tab_A_ref = a_ref.uuid, 
     tableC INNER JOIN tableA AS b_ref ON tableC.tab_A_ref = b_ref.uuid 
+0

当然应该是'FROM tableB INNER JOIN tableA AS a_ref ON tableB.tab_A_ref = a_ref, INNER JOIN tableC ON tableC.tab_A_ref = tableA.uuid'? – ADyson

+0

@ADyson - 可以,这取决于他想达到的目标。 (我发现所需的输出很难从OP中确定...但我相信这会“修复”所引发的错误)。实际上,查询将加入从tableB到tableC的所有内容,其中任何一个表在表A中都有匹配的记录。从语法上讲,我相信这是有效的(不进行测试) - 但我同意,没有任何“逻辑”上下文(并且可能不会给出OP的预期)。 – wally

+1

是真的。同样,正如我上面提到的,它看起来像数据结构可能有点不规范,这使得事情比他们需要的更复杂。 – ADyson

0

以下JOIN逻辑是不正确的:

tableB INNER JOIN tableA on tableB.tab_A_ref = tableA.uuid, 
    tableC INNER JOIN tableA on tableC.tab_A_ref = tableA.uuid 

查询应该是:

SELECT 
    tableB.uuid, tableB.ttl, tableB.ord, tableB.tab_A_ref 
FROM tableB 
    INNER JOIN tableA 
      ON tableB.tab_A_ref = tableA.uuid 
    INNER JOIN tableC 
      ON tableC.tab_A_ref = tableA.uuid 


这里使用的逻辑的本质是,第一个JOIN已经创建了虚拟单元,可以根据需要与任何其他表连接。tableA已经参与该JOIN,除非有特殊需要(在这里似乎不是这种情况),您不需要在查询中再次指定它。

相关问题