トップページに戻る    次のSQLパズルへ    前のSQLパズルへ

5-16 exists同士の論理積

SQLパズル

tblMember
メンバID   名前
--------   ----
   A       山田
   B       佐藤
   C       山下
   D       上田

tbl組
組ID  メンバID
----  --------
  1       A
  2       A
  2       B
  3       A
  3       C
  4       C
  5       C

1組,2組,3組の全てに属するメンバーを出力する。

出力結果
メンバID  名前
--------  ----
    A     山田


データ作成スクリプト

create table tblMember(
メンバID char(1),
名前 char(4));

create table tbl組(
組ID number,
メンバID char(1));

insert into tblMember(メンバID,名前) values('A','山田');
insert into tblMember(メンバID,名前) values('B','佐藤');
insert into tblMember(メンバID,名前) values('C','山下');
insert into tblMember(メンバID,名前) values('D','上田');
insert into tbl組(組ID,メンバID) values(1,'A');
insert into tbl組(組ID,メンバID) values(2,'B');
insert into tbl組(組ID,メンバID) values(2,'A');
insert into tbl組(組ID,メンバID) values(3,'A');
insert into tbl組(組ID,メンバID) values(3,'C');
insert into tbl組(組ID,メンバID) values(4,'C');
insert into tbl組(組ID,メンバID) values(5,'C');
commit;


SQL

--■■■existsを使用する方法■■■
select メンバID,名前 from tblMember a
where exists(select 1 from tbl組 b
              where b.メンバID = a.メンバID
                and b.組ID=1)
  and exists(select 1 from tbl組 b
              where b.メンバID = a.メンバID
                and b.組ID=2)
  and exists(select 1 from tbl組 b
              where b.メンバID = a.メンバID
                and b.組ID=3);

--■■■intersectを使用して、共通集合を求める方法■■■
select メンバID,名前 from tblMember a
where メンバID
in(select b.メンバID from tbl組 b where b.組ID=1 intersect
   select b.メンバID from tbl組 b where b.組ID=2 intersect
   select b.メンバID from tbl組 b where b.組ID=3);

--■■■分析関数を使う方法■■■
select distinct メンバID,名前
from (select a.メンバID,a.名前,
      count(case when b.組ID in(1,2,3) then b.組ID end)
      over(partition by a.メンバID) as カウント
      from tblMember a,tbl組 b
      where a.メンバID = b.メンバID)
where カウント = 3;

--■■■having句でブール代数を使う方法■■■
select a.メンバID,a.名前
  from tblMember a,tbl組 b
 where a.メンバID = b.メンバID
group by a.RowID,a.メンバID,a.名前
having max(case when b.組ID = 1 then 1 else 0 end)
     * max(case when b.組ID = 2 then 1 else 0 end)
     * max(case when b.組ID = 3 then 1 else 0 end) = 1;


解説

existsは、共通集合で代用でき、
not existsは、差集合で代用できます。