通过多个分组连接多个表

时间:2016-02-27 10:21:33

标签: sql sql-server join left-join query-optimization

我们有一个传递控制系统,每个传递操作都存储在Event MSSQL Server表中。我们希望根据它们之间的关系将多个表与Event表连接起来,如下图所示。但是,我不确定我使用的分组方法是否正确,因为查询需要花费大量时间。能否请您澄清一下如何通过多个分组加入这些表格?这是我使用的JOIN子句:

SELECT t.CardNo, t.EventTime, t1.EmployeeName, 
    t1.Status, t2.EventCH, t3.DoorName, t4.JobName, t5.DeptName 
FROM Event t 

LEFT JOIN Employee AS t1 ON t.EmployeeID = t1.ID 
LEFT JOIN EventType AS t2 ON t.EventTypeID = t2.ID 
LEFT JOIN Door AS t3 ON t.DoorID = t3.ID 
LEFT JOIN Job AS t4 ON t1.JobID = t4.ID 
LEFT JOIN Department AS t5 ON t1.DepartmentID = t5.ID

ORDER BY t.EventID Desc

enter image description here

更新:发布以下执行计划:

enter image description here

2 个答案:

答案 0 :(得分:1)

嘿,您是否尝试创建两个CTE来对连接进行分组?

因此,在一个CTE中为Employee,Department和Job创建一个联接。 对于其他CTE,为Event,Eventtype和Door创建一个连接。最后,使用员工ID和ID加入两个CTE。

将连接的表聚合在一起可能比一次性完成连接更快。顺便说一下,每个表的唯一约束是什么?

;WITH a AS

(
SELECT
    t1.ID
   ,t1.EmployeeName
   ,t1.Status
   ,t4.JobName
   ,t5.DeptName
FROM
    Employee t1
LEFT JOIN Job t4
    ON t1.JobID = t4.ID
LEFT JOIN Department t5
    ON t1.DepartmentID = t5.ID
)
,b AS
(
SELECT
    t.EmployeeID
   ,t.CardNo
   ,t.EventTime
   ,t2.EventCH
   ,t3.DoorName
FROM
    [Event] t
LEFT JOIN EventType t2
    ON t.EventTypeID = t2.ID
LEFT JOIN Door t3
    ON t.DoorID = t3.ID 
)

SELECT
    *
FROM
    b
LEFT JOIN a
    ON b.EmployeeID = a.ID

答案 1 :(得分:1)

您问题中的查询不代表查询计划中的查询。特别是,它具有条件

RIGHT(t.cardno, 8) = RIGHT(t1.cardno, 8)

函数的使用排除了计划索引的使用。

我的建议是为每个表添加一个虚拟列,对其进行索引,然后在连接中使用它:

alter table tEvent add cardno8 as RIGHT(cardno, 8);
alter table tEmployee add cardno8 as RIGHT(cardno, 8);

create index idx_tEvent_cardno8 tEvent(cardno8);
create index idx_tEmployee_cardno8 tEmployee(cardno8);

如果您将比较更改为:

,这应该有助于提升效果
on t.cardno8 = t1.cardno8

此外,您的查询没有WHERE子句,因此它(可能)处理了大量数据。