2014-08-29 67 views
0

我有以下表加入1表1第2分列在另一张表

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

Queue 
    ID 
    1 
    2 
    3 
    4 

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

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

+0

在这种情况下,请修改您的原始问题。你有多个已经熟悉你情况的人的建议。 – 2014-08-29 18:49:39

+0

我原来的问题已经有了多个答案,这完全改变了这个问题成为一个新的问题走这条路线。 – mameesh 2014-08-29 18:50:36

+0

我只是做像'表t合并(t。OverrideQId,t.QueueId)= a.ParameterId' – CSharper 2014-08-29 20:07:51

回答

1

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

0

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

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

0

检查该查询返回你要查找的内容:

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

不知道这查询的数据hudge量的情况下的性能。

希望这会帮助你解决你的问题。

0

从 队列q试此 选择* 内连接 (选择*,ISNULL(orderedqueueid,queueid),如从雇员joinedqueueid)为e 在q.id = e.joined QueueId;

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 
0

如果你对员工表正确的索引...你可以去让CTE分别为Null和NotNull版本执行单独的连接SQL,并在最外层的Select中完成所有的联合。

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);