如何将UNION语句转换为JOIN语句



我有三个表。

Table: Location
ID   | Name
-------+--------
1    | Paris
2    | London
3    | Sydney
Table: Loc_Map
PrimaryLoc | SecondaryLoc
-----------+-----------
1      | 3
Table: User
ID  | PrimaryLocID
----+-------------
22  |    1

我想要这个输出,对于userID:22。

LocationID | LocationName
1      |    Paris
3      |    Sydney

请注意,结果包含使用映射表映射的两个位置ID的数据。我已经使用UNION运算符获得了所需的输出,如下所示:

SELECT L.id, L.name 
FROM 
location L 
INNER JOIN Loc_Map LM ON L.id = LM.PrimaryLoc
INNER JOIN User U ON U.PrimaryLocID = LM.loc_id
WHERE U.id = 22
UNION
SELECT L.id, L.name
FROM 
location L INNER JOIN User U ON L.id = U.PrimaryLocID
WHERE U.id = 22

为了增强性能,我试图将这个SQL查询转换为JOIN语句,但不能。一个primaryloc可以有多个secondaryloc。我试着尽可能好地格式化这个问题,但如果有什么奇怪的地方,请原谅我在格式化方面缺乏经验。我也努力想出一个合适的通用问题标题,但除了给定的标题外,我找不到其他标题。如果你想到一些,请告诉我。

我使用的是SQL Server 2000。

为什么不只是:

SELECT L.id, L.name 
FROM 
location L 
INNER JOIN Loc_Map LM ON L.id in (LM.PrimaryLoc, LM.SecondaryLoc)
INNER JOIN User U ON U.PrimaryLocID = LM.loc_id
WHERE U.id = 22

然而,请注意,工会在任何一般意义上都不会"跑赢"工会。它们是两种不同的东西。

给定样本数据,这应该有效:

SELECT DISTINCT L.ID LocationID, L.Name LocationName
FROM user u
JOIN loc_map lm ON u.primarylocID = lm.primaryloc
JOIN location l ON l.id = lm.primaryloc 
OR l.id = lm.secondaryloc
WHERE U.id = 22

因为您只从location中进行选择,所以在join:之前会想到exists

SELECT L.id, L.name 
FROM location L 
WHERE EXISTS (SELECT 1
FROM Loc_Map LM INNER JOIN
User U
ON U.PrimaryLocID = LM.loc_id
WHERE L.id = LM.PrimaryLoc AND U.id = 22
) OR
EXISTS (SELECT 1
FROM User U 
WHERE L.id = U.PrimaryLocID AND U.id = 22
);

为了提高性能,您需要User(PrimaryLocID, id)Loc_Map(PrimaryLoc, locId)上的索引。

这应该能满足您的需要,不需要单独或联合。

select
l.ID LocationID,
l.Name LocationName
from location l
where
exists
(
select *
from Loc_Map lm
inner join [User] u
on u.PrimaryLocID = lm.PrimaryLoc
where
u.id = 22
and
(
l.id = lm.PrimaryLoc
or
l.id = lm.SecondaryLoc
)
)

最新更新