首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >根据列值连接不同的表

根据列值连接不同的表
EN

Stack Overflow用户
提问于 2014-06-12 12:12:22
回答 2查看 3.3K关注 0票数 5

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

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

代码语言:javascript
复制
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;

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

选择r.id,r.pid,p.type。

选择r.id,r.pid,p.type,c.name。

Preudocode:

代码语言:javascript
复制
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;

p.type的值可以从C和D增加到E,F,G,……)我倾向于只加入p.type指定的一个表,而不是使用UNION (首先是所有可能的表)。Whereby...since结果中的列数不同,UNION尝试以错误代码1222结尾:

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

这有可能..。怎么做呢?

EN

回答 2

Stack Overflow用户

发布于 2014-06-12 12:16:17

您的伪代码可以实现为:

代码语言:javascript
复制
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;

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

票数 6
EN

Stack Overflow用户

发布于 2014-06-12 12:20:18

@GordonLinoff的一个类似的但可替代的答案是将表C和D合并到一个表中。

这可以通过一个真正的单表、一个视图或一个内联视图来完成,后者我将在下面展示.

代码语言:javascript
复制
SELECT
  r.id,
  r.pid,
  p.type,
  z.name
FROM
  R   AS r
LEFT JOIN
  P   AS p
    ON r.pid = p.pid
LEFT JOIN
(
  SELECT 'D' AS type, pid, ''   AS name FROM D
  UNION ALL
  SELECT ''  AS type, pid, name AS name FROM C
)
  AS z
    ON  z.type = p.type
    AND z.pid  = p.pid
WHERE
  r.id = 123
LIMIT
  1
;

这种结构通常可以通过减少重复来简化代码,但也可以帮助优化器(取决于索引等)减少联接中所需的工作量。

注意:因为联合的表在第一个字段中有标量常量,而且由于联接中使用了该字段,所以优化器能够(取决于RDBMS)避免对两个表进行冗余连接。(有足够的信息来“知道”要加入哪个表。)

编辑: OP发表评论后的

如果这两个表有很大的差异,使UNION变得不切实际,那么使用两个LEFT JOIN可能是最好的选择。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24184078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档