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

时间:2018-07-12 19:21:29

标签: sql sql-server

我有三个桌子。

Table: Location

  ID   | Name
-------+--------
  1    | Paris
  2    | London
  3    | Sydney

Table: Loc_Map

PrimaryLoc | SecondaryLoc
-----------+-----------
    1      | 3

Table: User

ID  | PrimaryLocID
----+-------------
22  |    1

我想要此输出,用于用户ID: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。

4 个答案:

答案 0 :(得分:4)

为什么不只是:

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

但是请注意,工会在任何一般意义上都不会“跑赢大市”。他们是两个不同的东西。

答案 1 :(得分:3)

鉴于您的示例数据,这应该可以工作:

if event.type == pygame.KEYDOWN:
     if event.unicode == '@':
           print("@ sign pressed")

答案 2 :(得分:2)

因为您仅从location中进行选择,所以exists早于join就出现了:

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)上建立索引。

答案 3 :(得分:0)

这应该为您提供所需的内容,而无需单独或合并。

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
        )
)