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

9-60 弱い重複を求める

SQLパズル

CustomersIDテーブル
custnbr  last_name   first_name  address  city_name  state_code  phone_nbr
-------  ----------  ----------  -------  ---------  ----------  ---------
      1  Smith       Mike              1  New York            1          1
      2  Darwin      Ken               1  New York            0          5
      3  Haxley      Kate              2  Chicago             1         10
      4  Darwin      John              9  Los                 0          5
      5  Haxley      Mick              2  Keswick             0         10
      6  羽柴        秀吉              2  長浜城               0         10
      7  織田        信長              2  岐阜城               0         10
      8  織田        信忠              2  岐阜城               0         10
      9  織田        信包              2  清洲城               0         10

last_nameが一致して、
かつ、
first_name,address,city_name,state_code,phone_nbrの5列の中で
少なくとも2列が一致する組み合わせを求める。

出力結果
custnbrA  custnbrB
--------  --------
       2         4
       3         5
       7         8
       7         9
       8         9

SQLパズル 第2版のパズル54 [隠れた重複行] を参考にさせていただきました


データ作成スクリプト

create table Customers(
custnbr    number(1) primary key,
last_name  varchar2(6),
first_name varchar2(4),
address    number(1),
city_name  varchar2(8),
state_code number(1),
phone_nbr  number(2));

insert into Customers values(1,'Smith' ,'Mike',1,'New York',1, 1);
insert into Customers values(2,'Darwin','Ken' ,1,'New York',0, 5);
insert into Customers values(3,'Haxley','Kate',2,'Chicago' ,1,10);
insert into Customers values(4,'Darwin','John',9,'Los'     ,0, 5);
insert into Customers values(5,'Haxley','Mick',2,'Keswick' ,0,10);
insert into Customers values(6,'羽柴'  ,'秀吉',2,'長浜城'   ,0,10);
insert into Customers values(7,'織田'  ,'信長',2,'岐阜城'   ,0,10);
insert into Customers values(8,'織田'  ,'信忠',2,'岐阜城'   ,0,10);
insert into Customers values(9,'織田'  ,'信包',2,'清洲城'   ,0,10);
commit;


SQL

select a.custnbr as custnbrA,
       b.custnbr as custnbrB
  from Customers a,Customers b
 where a.custnbr < b.custnbr
   and a.last_name = b.last_name
   and case when a.first_name = b.first_name then 1 else 0 end
      +case when a.address    = b.address    then 1 else 0 end
      +case when a.city_name  = b.city_name  then 1 else 0 end
      +case when a.state_code = b.state_code then 1 else 0 end
      +case when a.phone_nbr  = b.phone_nbr  then 1 else 0 end >= 2
order by a.custnbr,b.custnbr;


解説

case式の結果を足し算して、
一致した列の数を求めてます。