我有以下表格
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
答案 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);