在同一查询中使用左连接和内连接

时间:2012-03-13 13:49:31

标签: sql ms-access left-join inner-join

以下是我使用左连接按预期工作的查询。我想要做的是进一步添加另一个表过滤此查询,但是这样做有困难。我将调用此新表table_3,并希望添加table_3.rwykey = runways_updatable.rwykey。非常感谢任何帮助。

SELECT * 
FROM RUNWAYS_UPDATABLE 
LEFT JOIN TURN_UPDATABLE 
ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY 
WHERE RUNWAYS_UPDATABLE.ICAO = 'ICAO'
AND (RUNWAYS_UPDATABLE.TORA > 4000 OR LDA > 0) 
AND (TURN_UPDATABLE.AIRLINE_CODE IS NULL OR TURN_UPDATABLE.AIRLINE_CODE = '' 
OR TURN_UPDATABLE.AIRLINE_CODE = '') 

“的 * ** * ** * ** * *** 编辑以澄清 ** * ** * ** * ** * ** * ** 这是我想要使用的内连接的另一个语句,我想结合这两个语句。

SELECT * 
FROM RUNWAYS_UPDATABLE A, RUNWAYS_TABLE B
WHERE A.RWYKEY = B.RWYKEY

' * * *到目前为止我的建议是什么,但是语法错误

     SELECT RUNWAYS_UPDATABLE.*, TURN_UPDATABLE.*,  AIRPORT_RUNWAYS_SELECTED.* 
     FROM RUNWAYS_UPDATABLE
       INNER JOIN  AIRPORT_RUNWAYS_SELECTED 
          ON RUNWAYS_UPDATABLE.RWYKEY = AIRPORT_RUNWAYS_SELECTED.RWYKEY
     LEFT JOIN TURN_UPDATABLE
          ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY 

注意:如果我注释掉内连接并离开左连接,反之亦然,它可以工作,但是当我在查询中有两个连接时,那就是当我得到语法错误时。

7 个答案:

答案 0 :(得分:17)

请记住,在左连接中过滤右侧表应该在连接中完成。

select *
from table1 
  left join table2
    on table1.FK_table2 = table2.id
    and table2.class = 'HIGH'

答案 1 :(得分:6)

INNER_JOIN之前添加LEFT JOIN

  SELECT * 
  FROM runways_updatable ru
    INNER JOIN table_3 t3 ON ru.rwykey = t3.rwykey
    LEFT JOIN turn_updatable tu
      ON ru.rwykey = tu.rwykey
      AND (tu.airline_code IS NULL OR tu.airline_code = '' OR tu.airline_code = '')
  WHERE ru.icao = 'ICAO'
    AND (ru.tora > 4000 OR ru.lda > 0)

如果您在LEFT JOIN之前INNER JOIN,那么table_3如果turn_updatable中没有匹配的行,您将无法从table_3获得结果。这可能是您想要的,但由于runways_updatable的加入条件仅引用table_3,我认为您需要turn_updatable的结果,即使没有匹配LEFT JOIN中的一行。

修改

正如@NikolaMarkovinović指出的那样,你应该在连接条件中过滤你的runways_updatable,如上所示。否则,如果右侧表(turn_updatable)中未满足该条件,则不会从左侧表( SELECT [ru].*, [tu].*, [ars].* FROM [runways_updatable] AS [ru] INNER JOIN [airport_runways_selected] AS [ars] ON [ru].rwykey = [ars].rwykey LEFT JOIN [turn_updatable] AS [tu] ON [ru].rwykey = [tu].rwykey AND ([tu].airline_code IS NULL OR [tu].airline_code = '' OR [tu].airline_code = '') WHERE [ru].icao = 'ICAO' AND ([ru].tora > 4000 OR [ru].lda > 0) )获得结果。


编辑2 :OP提到这实际上是Access,而不是MySQL

在Access中,也许这是表别名的差异。试试这个:

{{1}}

答案 2 :(得分:6)

我终于明白了。谢谢你的帮助!!!

SELECT * FROM 
(AIRPORT_RUNWAYS_SELECTED 
 INNER JOIN RUNWAYS_UPDATABLE 
 ON AIRPORT_RUNWAYS_SELECTED.RWYKEY = RUNWAYS_UPDATABLE.RWYKEY) 
LEFT JOIN TURN_UPDATABLE ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY

答案 3 :(得分:1)

如果它只是您要添加的内部联接,请执行此操作。您可以在同一查询中添加任意数量的联接。如果这不是您想要的,请更新您的答案,但

  SELECT * 
  FROM RUNWAYS_UPDATABLE 
  LEFT JOIN TURN_UPDATABLE 
  ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY 
  INNER JOIN table_3
  ON table_3.rwykey = runways_updatable.rwykey
  WHERE RUNWAYS_UPDATABLE.ICAO = 'ICAO'
  AND (RUNWAYS_UPDATABLE.TORA > 4000 OR LDA > 0) 
  AND (TURN_UPDATABLE.AIRLINE_CODE IS NULL OR TURN_UPDATABLE.AIRLINE_CODE = '' 
  OR TURN_UPDATABLE.AIRLINE_CODE = '') 

答案 4 :(得分:1)

我不确定你想要什么。但也许是这样的:

SELECT RUNWAYS_UPDATABLE.*, TURN_UPDATABLE.*
FROM RUNWAYS_UPDATABLE
JOIN table_3 
    ON table_3.rwykey = runways_updatable.rwykey
LEFT JOIN TURN_UPDATABLE 
ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY 
WHERE RUNWAYS_UPDATABLE.ICAO = 'ICAO'
AND (RUNWAYS_UPDATABLE.TORA > 4000 OR LDA > 0) 
AND (TURN_UPDATABLE.AIRLINE_CODE IS NULL OR TURN_UPDATABLE.AIRLINE_CODE = '' 
OR TURN_UPDATABLE.AIRLINE_CODE = '') 

答案 5 :(得分:0)

在寻找如何使LEFT JOIN进一步依赖INNER JOIN时,我总是遇到这个问题。这是当我搜索“在同一查询中使用LEFT JOININNER JOIN”时搜索的示例:

SELECT *
FROM foo f1
LEFT JOIN (bar b1
  INNER JOIN baz b2 ON b2.id = b1.baz_id
) ON
  b1.id = f1.bar_id

在此示例中,仅当还找到b1时,才会包括b2

答案 6 :(得分:0)

对于Postgres,查询计划程序不保证联接的执行顺序。为了保证可以使用@Gajus解决方案,但如果内部联接表的列存在条件,则会出现问题。要么需要在各自的Join条件中仔细添加where子句,否则最好在内部join部分中使用子查询,然后将输出左连接。