ChatGPT解决这个技术问题 Extra ChatGPT

如何在多列上执行 INNER JOIN

我正在做一个家庭作业项目,我应该执行一个数据库查询,通过城市名称或机场代码查找航班,但 flights 表只包含机场代码,所以如果我想按城市搜索我必须加入 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 另一个在机场。
提示 2:因此,您还需要为 airports 表加上别名,以便知道如何区分它们(即使用 fairport 查找和 tairport 查找的 airport 表)。别名的 SQL 关键字是 AS(尽管它可以省略,即 ...JOIN airports [AS] FA ON FA.code = flight.tairport ...)

D
Daniel Vassallo

您可以通过为连接的表指定 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!
如果机场表很大,最好在多个条件下加入一次。类似 - flights f INNER JOIN airports a ON a.code = f.fairport OR a.code = f.tairport 请提出建议。
@Ankur-m 为什么你使用或不使用?
@PHPFan - 因为原始查询使用 OR,而不是 AND。
A
Asclepius

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

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

s
shriek

就像是....

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 机场。不过只加入一次会更快。
P
Phil Rykoff

如果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
R
Robbert

如果您想同时搜索 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
 ...

S
Subarnarekha
SELECT *
FROM flights
INNER JOIN airports
   ON ((airports.code = flights.fairport)
       OR (airports.code = flights.tairport))

OR 可以在上面的 JOIN 条件中使用吗