web-dev-qa-db-fra.com

Utilisation de la jointure gauche et de la jointure interne dans la même requête

Voici ma requête en utilisant une jointure gauche qui fonctionne comme prévu. Ce que je veux faire, c'est ajouter un autre tableau pour filtrer toujours plus cette requête, mais j'ai du mal à le faire. Je vais appeler cette nouvelle table table_3 et je veux ajouter où table_3.rwykey = runways_updatable.rwykey. Toute aide sera la bienvenue.

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 = '') 

'( * ** * ** * ** * *** ÉDITER POUR CLARIFIER ** * ** * ** * ** * ** * ** Voici l'autre déclaration que la jointure interne je voudrais utiliser et je voudrais combiner ces 2 déclarations .

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

'( * * * Ce que j'ai en ce qui concerne les conseils ci-dessous, mais erreur de syntaxe

     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 

REMARQUE: si je commente la jointure interne et laisse la jointure gauche ou vice versa, cela fonctionne, mais lorsque j'ai les deux jointures dans la requête, c'est quand je reçois l'erreur de syntaxe.

17
Will

N'oubliez pas que le filtrage d'une table de droite dans la jointure gauche doit être effectué dans la jointure elle-même.

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

Je l'ai finalement compris. Merci pour votre aide!!!

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

Ajoutez votre INNER_JOIN avant votre 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)

Si vous LEFT JOIN avant votre INNER JOIN, vous n'obtiendrez pas les résultats de table_3 s'il n'y a pas de ligne correspondante dans turn_updatable. Il est possible que ce soit ce que vous voulez, mais puisque votre condition de jointure pour table_3 uniquement des références runways_updatable, Je suppose que vous voulez un résultat de table_3, même s'il n'y a pas de ligne correspondante dans turn_updatable.

MODIFIER :

Comme l'a souligné @ NikolaMarkovinović, vous devez filtrer votre LEFT JOIN dans la condition de jointure elle-même, comme vous le voyez ci-dessus. Sinon, vous n'obtiendrez pas les résultats du tableau de gauche (runways_updatable) si cette condition n'est pas remplie dans le tableau de droite (turn_updatable).


EDIT 2: OP a mentionné qu'il s'agit en fait d'Access, et non de MySQL

Dans Access, c'est peut-être une différence dans les alias de table. Essayez plutôt ceci:

  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

Si c'est juste une jointure interne que vous souhaitez ajouter, faites-le. Vous pouvez ajouter autant de jointures que vous le souhaitez dans la même requête. Veuillez mettre à jour votre réponse si ce n'est pas ce que vous voulez,

  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

Je ne sais pas vraiment ce que tu veux. Mais peut-être quelque chose comme ça:

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

Pour Postgres, le planificateur de requêtes ne garantit pas l'ordre d'exécution de la jointure. Pour garantir, on peut utiliser la solution @Gajus, mais le problème se pose s'il existe une condition Where pour les colonnes de la table de jointure interne. Soit on exigerait d'ajouter soigneusement les clauses where dans la condition de jointure respective, soit il est préférable d'utiliser la sous-requête de la partie de jointure interne et de joindre à gauche la sortie.

0
Debasish Mitra

Je rencontre toujours cette question lorsque je cherche comment faire LEFT JOIN dépendent d'une autre INNER JOIN. Voici un exemple de ce que je recherche lorsque je recherche "en utilisant LEFT JOIN et INNER JOIN dans la même requête ":

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

Dans cet exemple, b1 ne sera inclus que si b2 est également trouvé.

0
Gajus