代码之家  ›  专栏  ›  技术社区  ›  user1451111

如何将union语句转换为join语句

  •  2
  • user1451111  · 技术社区  · 6 年前

    我有三张桌子。

    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语句,但无法将其转换为join语句。 primaryloc 可以有多个 secondaryloc 我尽量把这个问题的格式设置得很好,但如果有什么奇怪的地方,请原谅我在格式设置方面缺乏经验。我也努力想出一个合适的通用题名,但除了给定的题名,我没法找到。如果你想一些,请告诉我。

    我正在使用SQL Server 2000。

    4 回复  |  直到 6 年前
        1
  •  3
  •   Aaron Dietz    6 年前

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

    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
    
        2
  •  4
  •   user1443098    6 年前

    为什么不只是:

    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
    

    然而,请注意,在任何一般意义上,工会都不会“超越”加入。它们是两种不同的东西。

        3
  •  2
  •   Gordon Linoff    6 年前

    因为你只能选择 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) .

        4
  •  0
  •   Bobby    6 年前

    这应该给你所需要的,不需要任何区别或联合。

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