2011-12-29 7 views
0

3つの基本的な問合せが互いに関連しており、結果として1つの結果セットが必要です。は、1つの結果セットを作成できません。オラクルの結合またはサブクエリ

簡体:

Query1を(可能な戻りないショーストッパーリターンヌル):

SELECT * FROM monkey WHERE monkey.ENDDATE IS NULL AND monkey.TEMPLATEID = 1 

QUERY2(可能な戻りないショーストッパーリターンヌル):

SELECT * FROM banana WHERE banana.ENDDATE IS NULL AND banana.TEMPLATEID = 1 

Query3(何かを返さなければなりません):

SELECT * FROM tree WHERE tree.TEMPLATEID = 1 

クエリ1と2は値を返すこともあれば返さないこともあります(nullに戻る)。

3番目のクエリが結果を返す必要があるかどうか3番目のクエリで何かが返され、クエリ1または2が失敗した場合でも何かを返す必要があります。

2つのクエリで外部結合を行うことはできません。なぜなら、oracleはエラーを私に言わせないからです... a.b (+) = b.b and a.c(+) = c.c is not allowed instead turn b+c into a view

私は論理的な理由を理解していると思います。決して、私はクエリ3を返す必要があり、クエリ1,2、または1と2を1つの結果セットとして3と共に返します。

これは意味があると思います。

+0

3つのクエリが同じ数と種類の列を返しますか?もしそうなら、結果を「結合」することはできますが、3つのテーブルから来る可能性は低いでしょう。 –

+0

実際には、各テーブルで1つの行が一致すると仮定して、3つのすべてのテーブルの列を含む1つの行、または(最大)3つの行を表示するかどうかはわかりません。 –

+0

クエリはクエリ3に関連するさまざまなものを返します。sometingが発生し、テーブル1とテーブル2が更新されない場合、テンプレートIDに基づいて何かが返されることを第3者が止めないという前提があります。削除された終了日は、クエリ3の間違いであるヌルです... –

答えて

4

あなたはORA-01417をヒットしているようです。

with banana as (select 'yellow' as colour, 1 as template_id, null as enddate 
     from dual), 
    monkey as (select 'capuchin' as monkeytype, 1 as template_id, null as enddate 
     from dual), 
    tree as (select 'tropical' as treetype, 1 as template_id from dual) 
select t.treetype, b.colour, m.monkeytype 
from tree t, banana b, monkey m 
where t.template_id = 1 
and b.template_id (+) = t.template_id 
and b.enddate (+) is null 
and m.template_id (+) = t.template_id 
and m.enddate (+) is null 
and m.template_id (+) = b.template_id; 

Error at Command Line:10 Column:22 
Error report: 
SQL Error: ORA-01417: a table may be outer joined to at most one other table 
01417. 00000 - "a table may be outer joined to at most one other table" 
*Cause: a.b (+) = b.b and a.c (+) = c.c is not allowed 
*Action: Check that this is really what you want, then join b and c first 
      in a view. 
:もちろん完全に不自然な方法で - あなたがいずれかを提供していないよう構成されたテーブルとデータを使用して、または結合条件、私は外 treebananaの両方に monkeyに参加しようとすることで同じ効果を得ることができます

あなたが使用している場合(9iのため、私は思う)ANSI Oracle固有(+)表記むしろ、あなたがより行うことができ、結合構文を「新しい」:

with banana as (select 'yellow' as colour, 1 as template_id, null as enddate 
     from dual), 
    monkey as (select 'capuchin' as monkeytype, 1 as template_id, null as enddate 
     from dual), 
    tree as (select 'tropical' as treetype, 1 as template_id from dual) 
select t.treetype, b.colour, m.monkeytype 
from tree t 
left join banana b on b.template_id = t.template_id 
    and b.enddate is null 
left join monkey m on m.template_id = t.template_id 
    and m.enddate is null 
    and m.template_id = b.template_id 
where t.template_id = 1; 

TREETYPE COLOUR MONKEYTYPE 
-------- ------ ---------- 
tropical yellow capuchin 

は上の制限の一部についてdocumentationを参照してください。 (+);オラクル社ではANSIバージョンの使用を推奨していますが、ドキュメントの例ではほとんどの時間を使用しているようです。

1

"monkey"、 "banana"、および "tree"の表の列の型がすべて異なると思われます。そうしないと、UNIONまたはUNION ALL演算子を使用して簡単に求めることができます。

また、テーブルdefnを共有していないためです。これらのテーブルのうち、私はあなたがこれらのテーブルに参加するための外部キーを持っているかどうかわかりません。だから私は彼らが完全に無関係であると仮定しています。

....これら2つの仮定と異なるので、ここでは、クエリから結合ResultSetを返すので、別の方法です。

SELECT CURSOR(QRY1), CURSOR(QRY2), CURSOR(QRY3) FROM DUAL; 

これはあなたに1つのクエリですべての3つの結果セットを提供します。しかし、それぞれの結果セットは、アプリケーションでナビゲートする必要がある参照カーソルです。

javaを使用する場合、3つの列のそれぞれのJava型は、個別のクエリ結果を取得するためにナビゲートする必要があるResultSetです。

助け

String qry1= "SELECT * FROM monkey WHERE monkey.ENDDATE IS NULL"; 
String qry2 = " SELECT * FROM banana WHERE banana.ENDDATE IS NULL AND banana.TEMPLATEID = 1"; 
String qry3= "SELECT * FROM tree WHERE tree.ENDDATE IS NULL AND tree.TEMPLATEID = 1"; 

String qry = "SELECT CURSOR("+qry1+"), CURSOR("+qry2+"), CURSOR("+qry3+") FROM DUAL"; 

ResultSet rs = conn.createStatement().executeQuery(qry); 

if(rs.next()) { //no while loop necessary, as we are expecting only one row 

    ResultSet rs1 = (ResultSet) rs.getObject(1); 
    ResultSet rs2 = (ResultSet) rs.getObject(2); 
    ResultSet rs3 = (ResultSet) rs.getObject(3); 


    while(rs1.next()) { 
     // retrive results of qry1 
    } 

    // same for rs2 and rs3 
} 

希望。

関連する問題