2015-03-03 61 views
0

我有类似下面的两个表:TSQL加入替换工会

档案表

 
Id | ServiceId | AccessLevel 
---------------------------- 
1 | 123  | 1 
2 | 123  | 1 
3 | 123  | 2 

附加档案表(简档是一个外键Profile.Id)

 
Id | ProfileId | AccessLevel 
---------------------------- 
1 | 1   | 2 
2 | 1   | 3 
3 | 2   | 2 
4 | 3   | 3 

我目前有一个视图,在这两个表上做一个UNION ALL,以便我可以查询它“简档= 1”,得到以下结果集:

 
ProfileId | ServiceId | AccessLevel 
----------------------------------- 
1   | 123  | 1 
1   | 123  | 2 
1   | 123  | 3 

这似乎是很慢的。

所以,我想知道如果/如何我可以得到这个相同的结果集使用单个查询,但我正在努力找出一种方法来做到这一点。

任何帮助,将不胜感激。视图后面

查询:

SELECT Id, ServiceId, AccessLevel FROM Profile 
UNION ALL 
SELECT P.Id, P.ServiceId, A.AccessLevel 
FROM Profile P 
INNER JOIN AdditionalProfile A ON A.ProfileId = P.Id 

每个表包含约160,000条记录。

+0

需要全部外部连接(如果有任何表是空的)。我猜想联盟全部更好...你确定它很慢?!? – jarlh 2015-03-03 11:55:27

+0

是啊,它似乎是 – kmcoulson 2015-03-03 12:00:27

+2

如果您的查询和查询计划,查询计划数量等查询缓慢,没有人可以帮助您根据所提供的信息对其进行优化。 – 2015-03-03 12:43:36

回答

0
SELECT p1.Id, p1.ServiceId, COALESCE(p2.AccessLevel, p1.AccessLevel) 
    FROM Profile p1 
    left join AdditionalProfile p2 
    on p2.ProfileId = p1.Id 
    and p2.AccessLevel <> p1.AccessLevel 

能使用ISNULL而不是COALESCE

用(正常)观点的问题则没有索引

更重要的是使之成为一个存储过程
如果Id和简档被索引此将吸烟快速

SELECT p1.Id, p1.ServiceId, ISNULL(p2.AccessLevel, p1.AccessLevel) 
    FROM Profile p1 
    left join AdditionalProfile p2 
    on p2.ProfileId = p1.Id 
    and p2.AccessLevel <> p1.AccessLevel 
where p1.ID = @ID 

OK尝试

SELECT p1.Id, p1.ServiceId, COALESCE(p2.AccessLevel, p1.AccessLevel) 
    FROM Profile p1 
outer join AdditionalProfile p2 
    on p2.ProfileId = p1.Id 
+0

嗨,感谢您的回复,但这不起作用。它只会从AdditionalProfile表中返回记录。 – kmcoulson 2015-03-03 17:00:55

+0

@kmcoulson不,它不仅仅返回AdditionalProfile记录。左连接返回左侧的所有行 - 这是左连接的作用。 – Paparazzi 2015-03-03 17:17:21

+0

对不起,再解释一下。我需要来自Profile的记录和来自AdditionalProfile的记录(即来自Profile的1行,来自AdditionalProfile的2行,共3行)。您的建议将只会从AdditionalProfile表中返回“AccessLevel”值,除非该表中没有记录,那么它将从Profile中返回“AccessLevel”值。 – kmcoulson 2015-03-03 18:47:36