Использование левого и внутреннего соединения в одном запросе - PullRequest
16 голосов
/ 13 марта 2012

Ниже приведен мой запрос с использованием левого соединения, которое работает, как и ожидалось.Что я хочу сделать, так это добавить еще одну таблицу, фильтрующую этот запрос еще дальше, но у меня возникают проблемы с этим.Я назову эту новую таблицу 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 

ПРИМЕЧАНИЕ. Если я закомментируювнутреннее соединение и выход из левого соединения или наоборот, это работает, но когда у меня есть оба соединения в запросе, это происходит, когда я получаю синтаксическую ошибку.

Ответы [ 6 ]

17 голосов
/ 13 марта 2012

Помните, что фильтрация правой таблицы в левом соединении должна выполняться в самом соединении.

select *
from table1 
  left join table2
    on table1.FK_table2 = table2.id
    and table2.class = 'HIGH'
6 голосов
/ 13 марта 2012

Я наконец понял это. Спасибо за вашу помощь !!!

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
6 голосов
/ 13 марта 2012

Добавьте ваш 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 нет подходящей строки.

EDIT

Как указал @ NikolaMarkovinović, вам следует отфильтровать LEFT JOIN в самом условии соединения, как вы видели выше. В противном случае вы не получите результаты из левой таблицы (runways_updatable), если это условие не выполнено в правой таблице (turn_updatable).

<ч />

EDIT 2 : OP упомянул, что это фактически Access, а не MySQL

В Access, возможно, это разница в псевдонимах таблиц. Попробуйте вместо этого:

  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)
1 голос
/ 13 марта 2012

Я не совсем уверен, что вы хотите. Но может быть что-то вроде этого:

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 = '') 
1 голос
/ 13 марта 2012

Если вы хотите добавить только внутреннее соединение, сделайте это. Вы можете добавить столько объединений, сколько хотите в одном запросе. Пожалуйста, обновите свой ответ, если это не то, что вы хотите, хотя

  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 = '') 
0 голосов
/ 29 июня 2019

Я всегда сталкиваюсь с этим вопросом, когда ищу, как заставить LEFT JOIN зависеть от дальнейшего INNER JOIN. Вот пример того, что я ищу, когда я ищу «используя LEFT JOIN и INNER 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...