2009-11-25 47 views
4

IM具有我的查詢一點語法問題(簡化):甲骨文JOIN USING +子查詢:ORA-00904字符串:無效標識符

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) 

通過使用 「使用」 關鍵字時,oracle犯規允許在表標識符列名的前面(如:t1.pk1,只有PK1可以使用)

如果我寫:

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) 

這個查詢將不會產生預期的結果。

但由於我使用的是「存在」子查詢,我怎樣才能加入這個子查詢?

當然,我想我可以用另一種方式寫這個查詢,避免存在,或者我不能使用「使用」。

但是有可能在where子句中將「連接/使用」與子查詢結合在一起?

編輯:使用Oracle 10gR2

回答

3

有趣的問題!同時仍然使用使用我可以管理的最好的是:

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

事實上,這是要做到這一點,而不完全避免使用的唯一方法(我個人更喜歡堅持JOIN..ON而不是使用)。 – 2009-11-26 04:11:52

1

您不能將表限定符與自然連接一起使用。

這個查詢:

select 1 from table4 t4 where t4.pk1 = pk1 

被解析爲

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

NOT EXISTS如果有,但table4一個記錄了它始終返回false。

只需使用明確JOIN條件:

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 
     )