2009-11-25 18 views
4

im ayant un petit problème de syntaxe dans ma requête (simplifiée):Oracle join En utilisant + sous-requête: string ora-00904: identifiant invalide

select * 
from table1 t1 
inner join table2 t2 using (pk1) 
inner join table3 t3 using (pk2) 
where not exists (select1 from table4 t4 where t4.pk1 = t1.pk1) 

En utilisant le "en utilisant" mot-clé, Oracle ne marche pas permettre l'identificateur de table devant le nom de la colonne (par exemple: t1.pk1, ne PK1 peut être utilisé)

Si j'écris:

select * 
from table1 t1 
inner join table2 t2 using (pk1) 
inner join table3 t3 using (pk2) 
where not exists (select1 from table4 t4 where t4.pk1 = pk1) 

Cette requête ne donnera pas les résultats escomptés.

Mais puisque j'utilise une sous-requête "exists", comment puis-je rejoindre cette sous-requête?

Bien sûr, je suppose que je pourrais écrire cette requête d'une autre manière et éviter l'existence, ou je ne pouvais pas utiliser "using".

Mais est-il possible d'avoir "join/using" combiné avec une sous-requête dans la clause where?

Edit: en utilisant Oracle 10gR2

Répondre

3

Problème intéressant! Le meilleur que je peux gérer tout en utilisant l'utilisation est:

select * from 
(select * 
    from table1 t1 
    inner join table2 t2 using (pk1) 
    inner join table3 t3 using (pk2) 
) v 
where not exists (select1 from table4 t4 where t4.pk1 = v.pk1) 
+0

En effet, c'est la seule façon de le faire sans éviter d'utiliser entièrement (Personnellement, je préfère coller à JOIN..ON plutôt que d'utiliser). –

1

Vous ne pouvez pas utiliser les qualificatifs de table avec les jointures naturelles.

Cette requête:

select 1 from table4 t4 where t4.pk1 = pk1 

est analysé comme

select 1 from table4 t4 where t4.pk1 = t4.pk1 

et NOT EXISTS sur elle retourne toujours faux s'il n'y a qu'un seul enregistrement à table4.

Il suffit d'utiliser JOIN explicites conditions:

WITH table1 AS 
     (
     SELECT 1 AS pk1 
     FROM dual 
     ), 
     table2 AS 
     (
     SELECT 1 AS pk1, 1 AS pk2 
     FROM dual 
     ), 
     table3 AS 
     (
     SELECT 1 AS pk2 
     FROM dual 
     ), 
     table4 AS 
     (
     SELECT 2 AS pk1 
     FROM dual 
     ) 
SELECT * 
FROM table1 t1 
JOIN table2 t2 
ON  t2.pk1 = t1.pk1 
JOIN table3 t3 
ON  t3.pk2 = t2.pk2 
WHERE NOT EXISTS 
     (
     SELECT 1 
     FROM table4 t4 
     WHERE t4.pk1 = t1.pk1 
     )