【问题标题】:Join multiple tables with same column name连接具有相同列名的多个表
【发布时间】:2015-08-18 00:26:22
【问题描述】:

我的 MySQL 数据库中有这些表:

总表:

+----generalTable-----+
+---------------------+
| id | scenario | ... |
+----+----------+-----+
| 1  | facebook | ... |
| 2  | chief    | ... |
| 3  | facebook | ... |
| 4  | chief    | ... |

Facebook 表:

+----facebookTable-----+
+----------------------+
| id | expiresAt | ... |
+----+-----------+-----+
| 1  | 12345678  | ... |
| 3  | 45832458  | ... |

主桌:

+------chiefTable------+
+----------------------+
| id | expiresAt | ... |
+----+-----------+-----+
| 2  | 43547343  | ... |
| 4  | 23443355  | ... |

基本上,通用表包含一些(显然)通用数据。基于generalTable.scenario,您可以在其他两个表中查找更多详细信息,这些表在某些列中很熟悉(例如expiresAt),但在另一些列中则不然。

我的问题是,如何在一次查询中得到generalTable的joined数据和正确的明细表。

所以,我想要这样的查询:

SELECT id, scenario, expiresAt 
FROM generalTable
    JOIN facebookTable
        ON generalTable.id = facebookTable.id
    JOIN chiefTable
        ON generalTable.id = chiefTable.id

还有这样的输出:

| id | scenario | expiresAt |
+----+----------+-----------+
| 1  | facebook | 12345678  |
| 2  | chief    | 43547343  |
| 3  | facebook | 45832458  |
| 4  | chief    | 23443355  |

但是,这不起作用,因为 facebookTable 和 ChiefTable 都有不明确的列名“expiresAt”。为了便于使用,我想保持这种方式。结果表也应该只有一列“expiresAt”,该列会自动填充来自 facebookTable 或 ChiefTable 的正确值。

我有一种感觉,这实际上是一项非常容易的任务,但对我来说这是一个漫长的工作日,而且你知道你会思考一个问题这么久却看不到可能简单的解决方案的日子。那么,你能帮帮我吗?

另外,很抱歉英语不好

【问题讨论】:

    标签: mysql sql join ambiguous


    【解决方案1】:

    您可能需要考虑将 expiredAt 添加到您的常规表中,并将其从其他表中删除,以删除架构中的重复项,并使此特定查询更简单。

    如果您需要坚持使用当前架构,您可以使用表别名来解决名称歧义,并使用两个连接和一个联合来创建您正在寻找的结果:

    SELECT g.id, g.scenario, f.expiresAt 
    FROM generalTable g
    JOIN facebookTable f
    ON g.id = f.id
    UNION ALL
    SELECT g.id, g.scenario, c.expiresAt 
    FROM generalTable g
    JOIN chiefTable c
    ON g.id = c.id;
    

    另一个答案中提到的外连接方法也可以解决问题。

    【讨论】:

    • 将 expiresAt 添加到通用表可能是最好的解决方案,但不幸的是,在这种特定情况下是不可能的。不过,感谢 UNION ALL 的解决方案。这就像一个魅力!
    【解决方案2】:

    您可以使用LEFT JOIN 来实现它。在结果字段中,您可以对常见字段 IF(fTbl.id IS NULL, cTbl.expiresAt, fTbl.expiresAt) AS expiresAt 执行类似操作。

    【讨论】:

    • 尽管这可能也行得通,但我认为上面使用 UNION ALL 语句的 mgrant 解决方案不太复杂,也更容易理解。
    • @bendenfield 这发生在我身上,但问题是表有不同的字段,并没有指定只需要常见的字段...但是您仍然可以使用UNION 通过在联合查询中为彼此的唯一字段创建“虚拟”空白字段来回答。
    • 您也可以使用COALESCE(cTbl.expiresAt, fTbl.expiresAt) 作为IF() 的替代品。它更简单,允许您有两个以上的选项,而无需链接多个 IF
    猜你喜欢
    • 2021-07-08
    • 2016-10-05
    • 1970-01-01
    • 1970-01-01
    • 2015-10-29
    • 2021-11-25
    • 2013-04-19
    • 2016-03-24
    相关资源
    最近更新 更多