MySQL连接:根据源表数据选择要连接的表

MySQL连接:根据源表数据选择要连接的表,mysql,sql,join,Mysql,Sql,Join,我觉得这个问题有点难以解释;可能有一些简洁的措词我不熟悉 TL/DR: 如何设置SQL查询以根据源表数据选择要联接的表? 我有一个事件表。每个事件都与四个主题中的一个相关;原始数据仅用于一个主题,因此是一个简单的1对1表关系 但是客户现在想要将事件扩展到四个不同的主题 因此: 可能的主题(每个主题都有自己的表): 示例: 假日表格 及 fundays表格 事件数据的主要来源是事件表 事件表 因此,每个事件都有一个参考表(topic\u type)和一个参考id(reference\u id)

我觉得这个问题有点难以解释;可能有一些简洁的措词我不熟悉

TL/DR:

如何设置SQL查询以根据源表数据选择要联接的表? 我有一个
事件表
。每个事件都与四个
主题中的一个相关
;原始数据仅用于一个
主题
,因此是一个简单的1对1表关系

但是客户现在想要将事件扩展到四个不同的主题

因此:


可能的主题(每个主题都有自己的表):

示例:

假日
表格 及

fundays
表格
事件数据的主要来源是事件表

事件表 因此,每个事件都有一个参考表(
topic\u type
)和一个参考id(
reference\u id

我现在的职位是想获得与每个活动相关的
假日
/
巡游
/
招聘
/
基金日
。我有事件Id,因此SQL应该是:

SELECT event_name, etc... FROM events WHERE event_id = 1 
但是我还想在同一个查询中检索主题的名称

我试过这样的方法:

这就是我被卡住的地方;我不知道如何动态引用要加入的表

我希望输出将是对无法访问的表的引用;如果我使用
CASE
根据列条件选择要联接的表,那么我设想select将始终引用3个无效的表引用,因此会引发问题


我希望输出为:

SELECT events.event_name, events.event_id, other_table.____ as topic_name ....
因此,SQL结果可以是:

事件id=1

事件id=2

事件id=3

  • 这可能吗
  • 如何做到这一点

我在这里看到:


但这些似乎都是无法完成的,或者它们的位置是同一个表中不同的列

您需要多个
左联接
s,取决于类型。我是这样想的:

SELECT m.field,
       COALESCE(s1.field, s2.field, s3.field, s4.field) AS field,
       ...
FROM main_table m
LEFT JOIN slave1_table s1 ON ...
LEFT JOIN slave2_table s2 ON ...
LEFT JOIN slave3_table s3 ON ...
LEFT JOIN slave4_table s4 ON ...
SELECT e.*,
       COALESCE(h.name, f.name, c.name, r.name) as name
FROM events e LEFT JOIN
     holidays h
     on h.id = e.reference_id AND
        e.topic_type = 'holiday' LEFT JOIN
     fundays f
     on f.id = e.reference_id AND
        e.topic_type = 'funday' LEFT JOIN
     cruises c
     on c.id = e.reference_id AND
        e.topic_type = 'cruise' LEFT JOIN
     recruitment r
     on f.id = e.reference_id AND
        e.topic_type = 'recruitment'    
WHERE e.event_id = 1 

还可以考虑这种方法:指定一个子查询、CTE甚至视图并与之连接,该子查询包含来自所有表的数据的并集。例如:

SELECT e.*,
       t.name
FROM events e INNER JOIN
    (
      SELECT id, 'holiday' as type, name FROM Holidays
      UNION ALL
      SELECT id, 'funday' as type, name FROM Fundays
      UNION ALL
      SELECT id, 'cruise' as type, name FROM Cruises
      UNION ALL
      SELECT id, 'recruitment' as type, name FROM Recruitments
    ) t
  ON
      t.id = e.reference_id AND
      t.type = e.topic_type

我个人喜欢尽可能避免使用函数,因为它们往往会对性能产生负面影响。

如果这样做有效,我会觉得自己是个十足的白痴@Martin不要忘记,从属表的所有条件都必须包含在ON中,而不是WHERE中。或者它们必须使用与输出列表中相同的合并表达式。
SELECT events.event_name, other_table.
FROM events 
CASE 
LEFT JOIN holidays other_table ON events.topic_type = 'hol' AND events.reference_id = other_table.id
WHERE events.event_id = 1
SELECT events.event_name, events.event_id, other_table.____ as topic_name ....
  event_id | event_name | topic_name
 ------------------------------------------------------------
      1    |  something | basic holiday
   event_id | event_name | topic_name
------------------------------------------------------------
       2    | some name  | cruise Holiday title no.4
  event_id | event_name | topic_name
 ------------------------------------------------------------
      3    |   horses!  |  balloons!
SELECT m.field,
       COALESCE(s1.field, s2.field, s3.field, s4.field) AS field,
       ...
FROM main_table m
LEFT JOIN slave1_table s1 ON ...
LEFT JOIN slave2_table s2 ON ...
LEFT JOIN slave3_table s3 ON ...
LEFT JOIN slave4_table s4 ON ...
SELECT e.*,
       COALESCE(h.name, f.name, c.name, r.name) as name
FROM events e LEFT JOIN
     holidays h
     on h.id = e.reference_id AND
        e.topic_type = 'holiday' LEFT JOIN
     fundays f
     on f.id = e.reference_id AND
        e.topic_type = 'funday' LEFT JOIN
     cruises c
     on c.id = e.reference_id AND
        e.topic_type = 'cruise' LEFT JOIN
     recruitment r
     on f.id = e.reference_id AND
        e.topic_type = 'recruitment'    
WHERE e.event_id = 1 
SELECT e.*,
       t.name
FROM events e INNER JOIN
    (
      SELECT id, 'holiday' as type, name FROM Holidays
      UNION ALL
      SELECT id, 'funday' as type, name FROM Fundays
      UNION ALL
      SELECT id, 'cruise' as type, name FROM Cruises
      UNION ALL
      SELECT id, 'recruitment' as type, name FROM Recruitments
    ) t
  ON
      t.id = e.reference_id AND
      t.type = e.topic_type