两列任意匹配一列

水友居士的一个需求.
听他广东的普通话真是费劲.不过还是大概听明白了。

实验准备

Oracle

先创建Oracle的数字辅助表

  1. create table nums( 
  2.   id int primary key
  3. );

  4. insert into nums select level from dual connect by level<=50000;
  5. commit;



  1. create table t1(
  2.   userid int primary key,
  3.   fathername varchar2(32) ,
  4.   mothername varchar2(32) ,
  5.   CONSTELLATION varchar2(32)
  6. );

  7. truncate table t1;
  8. insert into t1 select 1,'王大锤','大嫂子','白羊座' from dual;
  9. insert into t1 select 2,'王钢蛋','绿茶','白羊座' from dual;
  10. insert into t1 select 3,'彪子','朴一生','白羊座' from dual;
  11. insert into t1 select 4,'朴一生','水鸡妹','白羊座' from dual;
  12. insert into t1 select 5,'刘英','永强','白羊座' from dual;
  13. insert into t1 select 6,'水鸡妹','彪子','白羊座' from dual;
  14. insert into t1 select 7,'乔治','约翰','金牛座' from dual;
  15. insert into t1 select 8,null,'永强','金牛座' from dual;
  16. insert into t1 select 9,null,'铁头','金牛座' from dual;
  17. insert into t1 select 10,'棒槌',null,'金牛座' from dual;
  18. insert into t1 select 11,'铁头',null,'金牛座' from dual;
  19. insert into t1 select 12,'约翰','约翰','金牛座' from dual;
  20. insert into t1 select 13,'绿茶',null,'金牛座' from dual;

  21. commit;
  22. select * from t1;



该表有用户ID,父亲名称,母亲名称和星座

查询:
    星座相同,父母任意一个名字相同的用户列表

中间运算的查询:

  1. select * from (
  2.     select
  3.     CONSTELLATION,
  4.     case when rn=1 then fathername when rn=2 then mothername end w ,
  5.     wmsys.wm_concat( distinct rn||'|'|| userid) useridlist
  6.     from t1 u1 ,
  7.     (select rownum rn from dual connect by level<=2)
  8.     where case when rn=1 then fathername when rn=2 then mothername end is not null
  9.     group by CONSTELLATION,case when rn=1 then fathername when rn=2 then mothername end
  10. ) t2 where instr(useridlist,',')>0;



按照居士的需求,得到最终结果的SQL如下
  1. SELECT  REGEXP_SUBSTR(useridlist, '[^,]+', 1, id) AS value_str   
  2. FROM nums,  
  3. (  
  4.    select CONSTELLATION,w,useridlist useridlist  from (  
  5.       select   
  6.       CONSTELLATION,  
  7.       case when rn=1 then fathername when rn=2 then mothername end w ,  
  8.       wmsys.wm_concat( distinct userid) useridlist  
  9.       from t1 u1 ,  
  10.       (select rownum rn from dual connect by level<=2)   
  11.       where case when rn=1 then fathername when rn=2 then mothername end is not null  
  12.       group by CONSTELLATION,case when rn=1 then fathername when rn=2 then mothername end   
  13.   ) t2 where instr(useridlist,',')>0  
  14. )  t3 where id<= (length(useridlist) - length(replace(useridlist,',',''))+1);  


但是我诚然不知道他查询这个有什么用.

如果是我,可能会查询这些信息



  1. select CONSTELLATION,w,nvl(k,'[汇总]'),userlist  
  2.   from (  
  3.   select    
  4.   CONSTELLATION,w,  
  5.   decode(substr(value_str,0,instr(value_str,'|')-1) , 1 , '父亲名称' , '母亲名称') k,  
  6.   substr(value_str,instr(value_str,'|')+1) userid,  
  7.   wm_concat(substr(value_str,instr(value_str,'|')+1)) userlist  
  8.   from (  
  9.     SELECT CONSTELLATION,w,   
  10.     REGEXP_SUBSTR(useridlist, '[^,]+', 1, id) AS value_str    
  11.     FROM nums,    
  12.     (    
  13.        select CONSTELLATION,w,useridlist useridlist  from (    
  14.           select     
  15.           CONSTELLATION,    
  16.           case when rn=1 then fathername when rn=2 then mothername end w ,    
  17.           wmsys.wm_concat( distinct rn||'|'||userid) useridlist    
  18.           from t1 u1 ,    
  19.           (select rownum rn from dual connect by level<=2)     
  20.           where case when rn=1 then fathername when rn=2 then mothername end is not null    
  21.           group by CONSTELLATION,case when rn=1 then fathername when rn=2 then mothername end     
  22.       ) t2 where instr(useridlist,',')>0    
  23.     )  t3 where id<= (length(useridlist) - length(replace(useridlist,',',''))+1)  
  24.   )  
  25.   group by rollup  
  26.   (  
  27.     CONSTELLATION,w,  
  28.     decode(substr(value_str,0,instr(value_str,'|')-1) , 1 , '父亲名称' , '母亲名称'),  
  29.     substr(value_str,instr(value_str,'|')+1)   
  30.   )  
  31.   having   
  32.   (  
  33.     (GROUPING(CONSTELLATION) =0 and GROUPING(w) =0 and GROUPING(decode(substr(value_str,0,instr(value_str,'|')-1) , 1 , '父亲名称' , '母亲名称')) =0 and GROUPING(substr(value_str,instr(value_str,'|')+1)) =0)  
  34.     or  
  35.     (GROUPING(CONSTELLATION) =0 and GROUPING(w) =0 and GROUPING(decode(substr(value_str,0,instr(value_str,'|')-1) , 1 , '父亲名称' , '母亲名称')) =1 and GROUPING(substr(value_str,instr(value_str,'|')+1)) =1)  
  36.   ) order by 1,2,3  
  37. ) ;  






请使用浏览器的分享功能分享到微信等