TSQL加入以替换union

时间:2015-03-03 11:53:18

标签: sql tsql join union union-all

我有两个类似于以下的表:

个人资料表

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

附加个人资料表(ProfileId是Profile.Id的外键)

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

我当前有一个视图在这两个表上执行UNION ALL,以便我可以查询它“ProfileId = 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条记录。

1 个答案:

答案 0 :(得分: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和ProfileId被编入索引,这将是快速吸烟

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 

好的尝试

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