web-dev-qa-db-ja.com

Oracleの左結合とwhere句のエラー

CREATE TABLE "ATABLE1"
  (
    "COLUMN1" VARCHAR2(20 BYTE),
    "COLUMN2" VARCHAR2(20 BYTE)
  );

CREATE TABLE "ATABLE2"
  (
    "COLUMN1" VARCHAR2(20 BYTE),
    "COLUMN2" VARCHAR2(20 BYTE)
  );

Insert into ATABLE1 (COLUMN1,COLUMN2) values ('A','1');
Insert into ATABLE1 (COLUMN1,COLUMN2) values ('B','2');

Insert into ATABLE2 (COLUMN1,COLUMN2) values ('A',null);
Insert into ATABLE2 (COLUMN1,COLUMN2) values ('A','1');
Insert into ATABLE2 (COLUMN1,COLUMN2) values ('A','2');

select ATABLE1.column1, count(ATABLE2.column1) 
    from ATABLE1 Left OUTER JOIN ATABLE2 on ATABLE1.column1 = atable2.column1
    GROUP BY ATABLE1.column1;

Result

COLUMN1              COUNT(ATABLE2.COLUMN1) 
-------------------- ---------------------- 
A                    3                      
B                    0    

これは期待どおりに機能します。重要なのは、ATABLE1のすべての行を常に表示し、いくつかの制限を適用することです。

select ATABLE1.column1, count(ATABLE2.column1) 
    from ATABLE1 Left OUTER JOIN ATABLE2 on ATABLE1.column1 = atable2.column1
    where atable2.column2 = '1'
    GROUP BY ATABLE1.column1;


COLUMN1              COUNT(ATABLE2.COLUMN1) 
-------------------- ---------------------- 
A                    1                      

左結合でもATABLE1のすべての列が表示されないのはなぜですか?どうすればそれらを表示させることができますか?

よろしくお願いします。

10
Rafa de Castro

WHEREフィルターをオプション/外部テーブルに追加する場合、クエリをINNER JOINに変更します。結合、派生テーブル、またはCTEに条件を追加する必要があります。

select ATABLE1.column1, count(ATABLE2.column1) 
    from ATABLE1 Left OUTER JOIN ATABLE2
         on ATABLE1.column1 = atable2.column1 AND atable2.column2 = '1'
    GROUP BY ATABLE1.column1;
7
gbn

左結合でもATABLE1のすべての列が表示されないのはなぜですか?どうすればそれらを表示させることができますか?

これは、クエリにATABLE.column1のみを返すように指示しているためです。 gbnまたはJackのクエリを使用する場合は、SELECT句でATABLE1。*(または具体的にそれぞれに名前を付ける)を指定するだけです。

select ATABLE1.*, count(ATABLE2.column1) 
from ATABLE1 Left OUTER JOIN ATABLE2
     on ATABLE1.column1 = atable2.column1 AND atable2.column2 = '1'
GROUP BY ATABLE1.column1;
3
Aaron

結合に条件を追加する の代わりに、フィルターでnullをテストします。

select ATABLE1.column1, count(ATABLE2.column1) 
    from ATABLE1 Left OUTER JOIN ATABLE2 on ATABLE1.column1 = atable2.column1
    where atable2.column2 is null or atable2.column2 = '1'
    GROUP BY ATABLE1.column1;

私はこのバリアントを好みますが、読みにくいと思うかもしれません:

select ATABLE1.column1, count(ATABLE2.column1) 
    from ATABLE1 Left OUTER JOIN ATABLE2 on ATABLE1.column1 = atable2.column1
    where decode(atable2.column2,'1',1,null,1,0)=1
    GROUP BY ATABLE1.column1;

これを行う唯一の理由は、なんらかの理由でフィルターに条件を設定できない場合です(これは、より複雑なクエリの場合に当てはまります)。