【问题标题】:SQL: How can we make a table1 JOIN table2 ON a table given in a field in table1?SQL:我们如何在 table1 的字段中给定的表上创建 table1 JOIN table2?
【发布时间】:2011-05-09 01:35:29
【问题描述】:

假设我有table1,其中有一列名为“table_name”。我使用table1.table_name 来存储数据库中另一个表的名称。可引用的表都有一个字段“target_id”。

可以在 JOIN 语句中使用 table_name 吗?

例如:

SELECT t1.*, t2.* FROM table1 AS t1
                  JOIN table1.table_name AS t2 ON t1.table1_id = t2.target_id

显而易见的解决方案是使用脚本(在我的例子中是 C++)首先获取表名,并从中构造一个 SQL 查询。问题是:我们可以绕过脚本直接在 SQL (MySQL) 中执行此操作吗?

编辑:What is dynamic SQL?

【问题讨论】:

  • 这种情况下动态 SQL 是要走的路。
  • @Gabe:请注意,我使用 mysql。这是特定于供应商的扩展吗?
  • 这很可能是应该更改模型的情况。您可以尝试通过本专栏描述您正在完成的工作,我们或许可以帮助您改进您的模型。
  • @Peter Lang,谢谢。我正处于定义我的模型的过程中。我仍然不确定要走哪条路,我正在权衡不同的选择,因此提出了这个问题。
  • 如果您需要这样做,我建议您的模型是错误的。为什么需要引用不同的表?请展示您提出的表格结构,也许我们可以帮助您更好地设计结构。

标签: mysql sql dynamic-sql


【解决方案1】:

您唯一的机会是执行 2 条 SQL 语句:

  • 选择你需要的表名
  • 使用此表名动态构建第二个查询以获取您需要的数据 - 直接使用 SQL 无法实现您想要的(而且听起来您在某些方面设计了错误的数据库 - 但是如果不知道它的目标是什么,这很难说)。

【讨论】:

  • 谢谢。您如何将我的查询翻译成您所说的 2 条 sql 语句?
  • 基本上,您需要构建一个字符串,然后将其作为 SQL 查询运行,而您无法从 SQL 内部执行此操作。您需要一些位于 SQL 之外的东西来运行查询。这可能就像 mysql 客户端一样简单。
  • 这听起来不像是一个优雅的解决方案。从我从 OP 的问题中可以看出,每一行都可以有一个不同的表来加入。
【解决方案2】:

我知道我迟到了,但我想提供一个不同的解决方案。我在审计表中经常看到这种事情。 table_name 列将引用“更改了哪个表”,table1_id 将引用该表中更改的行的 ID。在这种情况下,审计表指向了许多通常不会连接的不同表。

这里是:

SELECT t1.*, t2.*, t3.*, t4.*, t5.*

FROM table1 AS t1

left JOIN table2 AS t2 
    ON t1.table1_id = t2.target_id
    and t1.table_name = 'table2'

left JOIN table3 AS t3
    ON t1.table1_id = t3.target_id
    and t1.table_name = 'table3'

left JOIN table4 AS t4 
    ON t1.table1_id = t4.target_id
    and t1.table_name = 'table4'

left JOIN table5 AS t5 
    ON t1.table1_id = t5.target_id
    and t1.table_name = 'table5'

当然,主要缺点是每个可能被引用的表都需要显式包含在 SQL 命令中。

您可以使用它作为选择列表获得更优雅的输出:

SELECT 
     t1.*, 
     coalesce(t2.fieldA, t3.fieldA, t4.fieldA, t5.fieldA) as fieldA,
     coalesce(t2.fieldB, t3.fieldB, t4.fieldB, t5.fieldB) as fieldB

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-28
    相关资源
    最近更新 更多