web-dev-qa-db-ja.com

同じクエリで左結合と内部結合を使用する

以下は、期待どおりに機能する左結合を使用したクエリです。私がやりたいのは、このクエリをさらに別のテーブルフィルターに追加することですが、そうするのに問題があります。この新しいテーブルを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 = '') 

'*************編集して明確にする**​​*** ************これは、内部結合iが使用する他のステートメントであり、これら2つのステートメントを組み合わせたいと思います。 。

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 

注:内部結合をコメントアウトして左結合を残すか、その逆を行うと機能しますが、クエリに両方の結合がある場合、構文エラーが発生したときです。

17
Will

左結合の右側のテーブルのフィルタリングは、結合自体で行う必要があることに注意してください。

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

私はついにそれを理解しました。ご助力いただきありがとうございます!!!

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
Will

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)から結果を取得できません。


編集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)
6
Travesty3

追加するのが単なる内部結合の場合は、これを実行します。同じクエリに必要な数の結合を追加できます。これがあなたの望むものではない場合は、答えを更新してください

  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 = '') 
1
Justin Pihony

私はあなたが何を望んでいるか本当にわかりません。しかし、おそらく次のようなもの:

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
Arion

Postgresの場合、クエリプランナーは結合の実行順序を保証しません。保証には@Gajusソリューションを使用できますが、内部結合テーブルの列にWhere条件がある場合に問題が発生します。それぞれの結合条件にwhere句を慎重に追加する必要があるか、そうでない場合は、内部結合部分にサブクエリを使用し、出力を左結合する方がよいでしょう。

0
Debasish Mitra

LEFT JOINさらなる依存INNER JOIN。これは、「using 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も見つかります。

0
Gajus