将1个表中的2列连接到另一个表中的1列

时间:2014-08-29 18:47:13

标签: sql sql-server sql-server-2012 ssms

我有以下表格

Employee
    ID QueueID OverrideQueueID
    1    1         NULL
    2    2          3
    3    1          3
    4    4          NULL

Queue
    ID
    1
    2
    3
    4

我需要将这些表连接在一起。基本上,连接需要查看是否存在OverrideQueueID,如果是,则在连接中使用OverrideQueueID到QueueTable,如果不在连接中使用QueueID。 QueueID将始终存在,但OverrideQueueID有时为NULL。这将是数百万条记录加入到一个包含大约10条记录的表中,所以我不想去COALESCE路线,因为我在过去使用连接函数时看到了性能下降。我假设如果我去COALESCE路线,将始终执行表扫描以从COALESCE生成值。

这类似于我之前提出的以下问题,但现在我有1个表连接到1个表而不是1个表有条件地连接到多个表。我从原来的问题上取得了一些进展。        [Conditional join to two different tables based on 2 columns in 1 table

7 个答案:

答案 0 :(得分:1)

加入中的COALESCE或ISNULL仍然是要走的路。 如果表演不符合您的期望,请分析您的查询的执行计划,并根据结果编辑您的帖子。

答案 1 :(得分:0)

使用COALESCE函数使用员工ID和更正的QueueID填充临时表,然后索引该表。

然后加入到索引临时表中。这是否比在联接中使用函数更快,最好通过实验确定。

答案 2 :(得分:0)

检查此查询是否返回您要查找的内容:

SELECT E.*
FROM Employee E
INNER JOIN Queue Q ON Q.ID = ISNULL(E.OverrideQueueID, E.QueueID)

在数据量小的情况下,不确定此查询的性能。

希望这可以帮助您解决问题。

答案 3 :(得分:0)

试试这个 选择*来自 队列q 内部联接 (选择*,isnull(orderedqueueid,queueid)作为来自员工的joinedqueueid)作为e 在q.id = e.joined QueueId;

答案 4 :(得分:0)

另一种方法是使用Case语句......如下所示......

select 
e.ID as E_ID,
e.QueueID,
e.OverrideQueueID,
q.ID as Q_ID
From Employee e 
Join Queue q 
    On (Case When e.OverrideQueueID is Not Null Then e.OverrideQueueID Else e.QueueID End) = q.ID

第二选择

Select 
e.ID as E_ID,
e.QueueID,
Q.ID as Q_ID
(
select ID,QueueID from Employee Where OverrideQueueID is NULL
Union All
select ID,OverrideQueueID as QueueID from Employee Where OverrideQueueID is Not NULL
) e 
  Join Queue Q on e.QueueID = Q.ID

答案 5 :(得分:0)

如果您在员工表上有适当的索引......您可以选择CTE为Null和NotNull版本执行单独的连接SQL,并在最外面的Select处进行联合。

答案 6 :(得分:0)

要解决您的性能问题,另一个选择是将计算的持久列添加到employee表,然后索引此列并对其进行所有连接,而不是QueueId或OverrideQueueId。例如:


    ALTER TABLE dbo.Employee ADD ActiveQueueId AS COALESCE(OverrideQueueId, QueueId) PERSISTED;
    GO

    CREATE NONCLUSTERED INDEX IX_Employee_ActiveQueueId ON dbo.Employee (ActiveQueueId);