代码之家  ›  专栏  ›  技术社区  ›  Evan Carroll

如何基于表名在SQL中进行联接?

  •  0
  • Evan Carroll  · 技术社区  · 16 年前

    好吧,我们有一堆这样命名的表:

    training_data_001
    training_data_002
    training_data_003
    training_data_004
    training_data_005
    

    然后在另一个表中找到一个字段,我们称之为master.training_type。

    SELECT foo FROM master WHERE id = ? 
    INNER JOIN training_data_${master.training_type}
    ON foo.id = training_data_${master.training_type}.foo_id
    

    我知道我可以在客户端做到这一点,但是让数据库来做会很好。

    另请注意:它是SQL Server。

    :我决定只在客户端做。无论如何,谢谢大家。

    谢谢!

    -氟利昂

    5 回复  |  直到 16 年前
        1
  •  2
  •   gbn    16 年前

    只能使用动态SQL读取master.training_type来生成字符串,然后使用 EXEC (@stringvar)

        2
  •  1
  •   Cade Roux    16 年前

    只能使用存储过程中的动态SQL来完成此操作。如果出于安全或其他原因不想动态生成视图或存储过程,也可以使用代码生成提前生成视图或存储过程。

        3
  •  1
  •   ConcernedOfTunbridgeWells    16 年前

    如果表都是相同的结构,请创建 Partitioned View

        4
  •  1
  •   TheSoftwareJedi jac    16 年前

    做这样的事:

    create view training_data_all as
    select '001' as training_type, * from training_data_001
    union all
    select '002' as training_type, * from training_data_002
    union all
    select '003' as training_type, * from training_data_003
    union all
    select '004' as training_type, * from training_data_004
    union all
    select '005' as training_type, * from training_data_005
    

    然后选择并连接到/从中选择:

    SELECT foo FROM master WHERE id = ? 
    INNER JOIN training_data_all
    ON foo.id = training_data_all.foo_id
    WHERE training_data_all.training_type = ${master.training_type}
    

    但这些都不是非常有效的。你能把这些数据以固定的间隔转换成一个组合表吗?

        5
  •  1
  •   Tom H zenazn    16 年前

    分区视图是一种可能的方法。由于您只选择FO列,您真的只是通过内部连接检查训练表中是否存在行?另外,看起来您试图在join中使用foo作为别名,但在SELECT子句中并没有这样设置。所以我猜你到底想要什么。

    另一个问题。。。这套训练表是静态的吗?您是否希望能够添加一个带有新后缀号的新表并使其正常工作?

    另一种可能的解决方案:

    SELECT
         foo
    FROM
         dbo.master m
    WHERE
         (training_type = '001' AND EXISTS (SELECT * FROM dbo.training_data_001 WHERE foo_id = m.id)) OR
         (training_type = '002' AND EXISTS (SELECT * FROM dbo.training_data_002 WHERE foo_id = m.id)) OR
         (training_type = '003' AND EXISTS (SELECT * FROM dbo.training_data_003 WHERE foo_id = m.id)) OR
         (training_type = '004' AND EXISTS (SELECT * FROM dbo.training_data_004 WHERE foo_id = m.id)) OR
         (training_type = '005' AND EXISTS (SELECT * FROM dbo.training_data_005 WHERE foo_id = m.id))
    

    如果您真的想从训练数据表返回列,那么可以使用如下方法:

    SELECT
         m.id,
         COALESCE(t1.my_col, t2.my_col, t3.my_col, t4.my_col, t5.my_col) AS my_col
    FROM
         dbo.master m
    LEFT OUTER JOIN dbo.training_data_001 t1 ON m.training_type = '001' AND t1.foo_id = m.id
    LEFT OUTER JOIN dbo.training_data_002 t1 ON m.training_type = '002' AND t2.foo_id = m.id
    LEFT OUTER JOIN dbo.training_data_003 t1 ON m.training_type = '003' AND t3.foo_id = m.id
    LEFT OUTER JOIN dbo.training_data_004 t1 ON m.training_type = '004' AND t4.foo_id = m.id
    LEFT OUTER JOIN dbo.training_data_005 t1 ON m.training_type = '005' AND t5.foo_id = m.id