根据列值连接不同的表

du-*_*-it 5 sql join

我有一个表R,其中包含表P的外键。表P中有一个列,告诉我表P中的记录是什么类型。与 P.type 列中的可能值相关,根据表存在。因此,如果 P.type 为“C”,则表示名为 C 的表,如果值为“D”,则表示名为 D 的表。

现在我想要一个 SELECT 语句,它根据 P.type 分别给出表 C 或 D 中的值。为了使其更复杂,结果中的列的数量/类型应有所不同。

SELECT r.id, r.pid, p.type, 
FROM R r 
LEFT JOIN P p ON r.pid = p.pid 
WHERE r.id = 123 LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

现在我已经得到了P表的记录。根据列类型的值,我想决定要在先前的查询中加入哪个表(C 或 D)。如果我必须连接表 D,则返回的列(结果集)应保持原样,但如果必须连接表 C,则应返回另一列。因此,SELECT 子句从

选择 r.id、r.pid、p.type FROM ...

选择 r.id、r.pid、p.type、c.name FROM ...

预编码:

SELECT r.id, r.pid, p.type(, c.name)   -- c.name my or may not be in the result depending on the joined table
FROM R r 
LEFT JOIN P p ON r.pid = p.pid 
if p.type = 'D' LEFT JOIN D d ON d.pid = p:pid end
if p.type = '' LEFT JOIN C c ON c.pid = p:pid end
WHERE r.id = 123 LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

Sind 可能要连接的表的数量可以扩展(p.type 的值可能从 C 和 D 增加到 E、F、G...)我更愿意只连接由p.type 而不是在所有可能的表之上使用 UNION。由于结果中的列数不同,UNION 尝试以错误代码 1222 结束:

使用的 SELECT 语句具有不同的列数。

这可能吗...以及如何实现?

Gor*_*off 6

您的伪代码可以实现为:

SELECT r.id, r.pid, p.type, coalesce(d.name, c.name)  
FROM R r LEFT JOIN
     P p
     ON r.pid = p.pid LEFT JOIN 
     D d
     ON p.type = 'D' and d.pid = p.pid LEFT JOIN
     C c
     ON p.type = '' and c.pid = p.pid end
WHERE r.id = 123
LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

假设表CD没有多行匹配,这将起作用。如果是这种情况,您可能需要预先聚合结果或使用子查询。