最近、いくつかのバグを修正しました。結合条件にrownumがありました。
このようなもの:t1.id=t2.idおよびrownum<2でt1を左結合します。したがって、「左結合」に関係なく、1行のみを返すことになっています。
これをさらに調べてみると、Oracleが「左結合」状態でrownumを評価する方法がわからないことがわかりました。masterとdetailの2つのサンプルテーブルを作成しましょう。
create table MASTER
(
ID NUMBER not null,
NAME VARCHAR2(100)
)
;
alter table MASTER
add constraint PK_MASTER primary key (ID);
prompt Creating DETAIL...
create table DETAIL
(
ID NUMBER not null,
REF_MASTER_ID NUMBER,
NAME VARCHAR2(100)
)
;
alter table DETAIL
add constraint PK_DETAIL primary key (ID);
alter table DETAIL
add constraint FK_DETAIL_MASTER foreign key (REF_MASTER_ID)
references MASTER (ID);
prompt Disabling foreign key constraints for DETAIL...
alter table DETAIL disable constraint FK_DETAIL_MASTER;
prompt Loading MASTER...
insert into MASTER (ID, NAME)
values (1, 'First');
insert into MASTER (ID, NAME)
values (2, 'Second');
commit;
prompt 2 records loaded
prompt Loading DETAIL...
insert into DETAIL (ID, REF_MASTER_ID, NAME)
values (1, 1, 'REF_FIRST1');
insert into DETAIL (ID, REF_MASTER_ID, NAME)
values (2, 1, 'REF_FIRST2');
insert into DETAIL (ID, REF_MASTER_ID, NAME)
values (3, 1, 'REF_FIRST3');
commit;
prompt 3 records loaded
prompt Enabling foreign key constraints for DETAIL...
alter table DETAIL enable constraint FK_DETAIL_MASTER;
set feedback on
set define on
prompt Done.
次に、このクエリがあります:
select * from master t
left join detail d on d.ref_master_id=t.id
結果セットは予測可能です。マスターテーブルのすべての行と、この条件d.ref_master_id=t.idに一致する詳細テーブルの3つの行があります。
次に、結合条件に「rownum = 1」を追加しましたが、結果は同じでした。
select * from master t
left join detail d on d.ref_master_id=t.id and rownum=1
最も興味深いのは、「rownum <-666」を設定して、同じ結果が得られたことです。
select * from master t
left join detail d on d.ref_master_id=t.id and rownum<-666.
結果セットにより、この条件は詳細テーブルの3行で「True」と評価されたと言えます。しかし、「内部結合」を使用すると、すべてが想定どおりになります。
select * from master t
join detail d on d.ref_master_id=t.id and rownum<-666.
rownumが-666未満になるとは想像できないため、このクエリは行を返しません:-)
さらに、外部結合にoracle構文を使用する場合、「(+)」を使用するとすべてがうまくいきます。
select * from master m ,detail t
where m.id=t.ref_master_id(+) and rownum<-666.
このクエリは行も返しません。
誰かが私に、アウタージョインとローナムで私が誤解していることを教えてもらえますか?