【问题标题】:How to do an INNER JOIN on multiple columns如何在多列上执行 INNER JOIN
【发布时间】:2011-01-22 22:23:06
【问题描述】:

我正在做一个家庭作业项目,我应该执行一个数据库查询,通过城市名称或机场代码查找航班,但 flights 表只包含机场代码,所以如果我想按城市搜索我必须加入airports 表。

airports 表具有以下列:code, city
航班表具有以下列:airline, flt_no, fairport, tairport, depart, arrive, fare
fairporttairport 列是 fromto 机场代码。
departarrive 列是出发和到达日期。

我想出了一个查询,它首先连接 fairport 列和 airports.code 列上的航班。为了让我匹配tairport,我必须对第一次加入的先前匹配执行另一个加入。

SELECT airline, flt_no, fairport, tairport, depart, arrive, fare
    FROM (SELECT * FROM flights
        INNER JOIN airports
        ON flights.fairport = airports.code
        WHERE (airports.code = '?' OR airports.city='?')) AS matches
    INNER JOIN airports
    ON matches.tairport = airports.code
    WHERE (airports.code = '?' OR airports.city = '?')

我的查询返回了正确的结果,足以满足作业的目的,但我想知道我是否可以在多个列上使用JOIN?我将如何构造WHERE 子句以使其与出发地和目的地城市/代码相匹配?

下面是关于我想要实现的“伪查询”,但我无法正确获取语法,我不知道如何表示出发地和目的地的 airports 表:

SELECT * FROM flights
INNER JOIN airports
ON flights.fairport = airports.code AND flights.tairport = airports.code
WHERE (airports.code = 'departureCode' OR airports.city= 'departureCity') 
    AND (airports.code = 'destinationCode' OR airports.city = 'destinationCity')

更新

我还发现this visual representation of SQL Join statements 作为关于如何构建 SQL 语句的一般指南非常很有帮助!

【问题讨论】:

  • 提示:您需要为每条记录查找两个城市(一个用于 fairport,另一个用于 tairport。因此可以(确实需要)有 两个 JOIN ,与 airports 表,但其中一个基于 fairport 另一个在 tairport。
  • 提示2:因此,您还需要为 airports 表加上别名,以便知道如何区分它们(即,使用 fairport 查找和 tairport 查找的 airport 表)。别名的 SQL 关键字是 AS(尽管它可以省略,即 ...JOIN airports [AS] FA ON FA.code = flight.tairport ...)

标签: sql database


【解决方案1】:

您可以通过为已连接的表指定alias 来多次加入同一个表,如下例所示:

SELECT 
    airline, flt_no, fairport, tairport, depart, arrive, fare
FROM 
    flights
INNER JOIN 
    airports from_port ON (from_port.code = flights.fairport)
INNER JOIN
    airports to_port ON (to_port.code = flights.tairport)
WHERE 
    from_port.code = '?' OR to_port.code = '?' OR airports.city='?'

请注意,to_portfrom_portairports 表的第一个和第二个副本的别名。

【讨论】:

  • 好的,我尝试了上述解决方案并出现以下错误:您的SQL语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 7 行的“INNER_JOIN airports to_port ON (to_port.code = flight.tairport) WHERE”附近使用正确的语法
  • 哦,我知道为什么 :) 它应该是 INNER JOIN 而不是 INNER_JOIN... DOH!
  • 如果 airports 表很大,最好在多个条件下加入一次。像 - flights f INNER JOIN airports a ON a.code = f.fairport OR a.code = f.tairport 请提出建议。
  • @Ankur-m 为什么你使用或不使用?
  • @PHPFan - 因为原始查询使用 OR,而不是 AND。
【解决方案2】:

类似......

SELECT f.*
      ,a1.city as from
      ,a2.city as to
FROM flights f
INNER JOIN airports a1
ON f.fairport = a1.code
INNER JOIN airports a2
ON f.tairport = a2.code

【讨论】:

  • 我已经在上面问过了,想在这里也会问 - 如果 airports 表很大(并且使用 WHERE 条件对整个查询有更多过滤器),最好只加入一次在多个条件下。像 - flights f INNER JOIN airports a ON a.code = f.fairport OR a.code = f.tairport 这样有什么不同吗?你怎么看?
  • 结果会有所不同,前者每个航班产生一行 from 和 to,您的建议是每个航班产生 2 行,一行来自 from 和一行 to 机场。不过只加入一次会更快。
【解决方案3】:

为什么不能在ON 子句中使用AND?例如:

SELECT *
FROM flights
INNER JOIN airports
   ON ((airports.code = flights.fairport)
       AND (airports.code = flights.tairport))

【讨论】:

    【解决方案4】:

    如果mysql适合你:

    SELECT flights.*, 
           fromairports.city as fromCity, 
           toairports.city as toCity
    FROM flights
    LEFT JOIN (airports as fromairports, airports as toairports)
    ON (fromairports.code=flights.fairport AND toairports.code=flights.tairport )
    WHERE flights.fairport = '?' OR fromairports.city = '?'
    

    编辑:添加示例以过滤代码或城市的输出

    【讨论】:

    • 为什么不直接使用airports.code 而不是fromairports.codetoairports.code?然后你就不需要as fromairports, airports as toairports了。
    【解决方案5】:

    如果您想同时搜索 FROM 和 TO 机场,您需要在 Airports 表中加入两次 - 然后您可以在结果集中同时使用 from 和 to 表:

    SELECT
       Flights.*,fromAirports.*,toAirports.*
    FROM
       Flights
    INNER JOIN 
       Airports fromAirports on Flights.fairport = fromAirports.code
    INNER JOIN 
       Airports toAirports on Flights.tairport = toAirports.code
    WHERE
     ...
    

    【讨论】:

      【解决方案6】:
      SELECT *
      FROM flights
      INNER JOIN airports
         ON ((airports.code = flights.fairport)
             OR (airports.code = flights.tairport))
      

      OR 可以像上面那样在 JOIN 条件中使用吗

      【讨论】:

        猜你喜欢
        • 2018-06-24
        • 2013-05-14
        • 2020-02-25
        • 1970-01-01
        • 2016-06-19
        • 2012-06-15
        • 2016-07-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多