在单个查询中将一个表的多个列连接到另一个表的单个列

Posted

技术标签:

【中文标题】在单个查询中将一个表的多个列连接到另一个表的单个列【英文标题】:Join multiple columns of one table to single column of another table in single query 【发布时间】:2014-10-30 11:17:24 【问题描述】:

这是我的查询

select u.FirstName as AssignedBy, u1.FirstName as RespondedBy, u2.FirstName as ClosedBy
from Messages M
left join User u on isnull(M.AssignedBy, 0) = u.UserId    
left join User u1 on isnull(M.RespondedBy, 0) = u1.UserId
left join User u2 on isnull(M.closedby, 0) = u2.UserId

是否可以在单个查询中编写连接?我想提高查询的性能,所以我不想进行 3 个连接,所以在一个连接中尝试它,因为我的 User 表有很多记录。我在两个表上都有所有索引。我试过了

select u.FirstName as AssignedBy, u.FirstName as RespondedBy, u.FirstName as ClosedBy
from Messages M
left join User u on 
(isnull(M.AssignedBy, 0) = u.UserId or isnull(M.RespondedBy, 0) = u.UserId or isnull(M.closedby, 0) = u.UserId)

但是这个查询给出了不正确的输出,因为我有很多行在所有三个连接列中都有记录。有没有其他方法可以达到同样的效果?

【问题讨论】:

你的表现有多差?您可以使用查询的执行计划来编辑您的问题吗? 【参考方案1】:

您的原始查询看起来不错。如果您在User(UserId) 或更好的User(UserId, FirstName) 上有索引,那么我认为性能会很好。

join 条件下使用or 通常会使性能变差而不是变好。

您的问题可能只是Messages 表的大小。返回非常大的结果集可能需要一段时间。

【讨论】:

是的,戈登,我的表确实很大,但我无法帮助它,因此尝试优化其他查询。我在 UserId 上有索引。【参考方案2】:

我认为没有“更好”的方法可以做到这一点。我唯一建议反对的是JOIN 中的ISNULL() 构造,因为它实际上没有任何用途,但可能会使优化器感到困惑。 查询确实“要求”您在 User 表上有适当的索引,但我假设 UserId 字段已经是所述表的 PK...

select u.FirstName as AssignedBy, 
       u1.FirstName as RespondedBy, 
       u2.FirstName as ClosedBy
from Messages M
left join User u on M.AssignedBy = u.UserId    
left join User u1 on M.RespondedBy = u1.UserId
left join User u2 on M.closedby = u2.UserId

性能到底有多差?您确定指向 User 表的链接是罪魁祸首吗? (我猜您还通过在 Messages 表上使用其他谓词来限制查询结果;例如,只想要打开的消息或最后 100 条消息等...)

(查询计划可能很有趣)

【讨论】:

我不确定 User 表是罪魁祸首,因为 Messages 表中有很多数据。我已经限制了查询的结果,还有很多过滤结果的 where 条件,但是我想知道我可以指定这部分查询吗? 在这种情况下,我会首先关注“其他”条件;用户表的(三重)连接看起来不错,因为它是恕我直言。就像我说的,看看查询执行计划,看看“重”部分在哪里。

以上是关于在单个查询中将一个表的多个列连接到另一个表的单个列的主要内容,如果未能解决你的问题,请参考以下文章

如何在 OpenOffice 中将一列单元格从一张表插入到另一张表的单个单元格中?

如何在 spark DataFrame 中将多个浮点列连接到一个 ArrayType(FloatType()) 中?

使用 codeigniter 将连接表中的列连接到另一列

如何在另一个数据库中的多个数据库中创建多个表的单个视图?

在单个查询中获取多个 SQL 表的列

在单个列中使用来自多个表的 ID