有一个这样的需求:
网站要实现联合行动功能,就是要进入某项活动需要组队才能一起,比如a要参加某项活动,他可以选择b,c,d。但b,c,d必须也要选择他,同时对于b也必须选择a、c、d,同理c、d也是如此。他们之间的关系都是双向对应关系,必须你选了我,我也选了你. 表关系如下:(表id:id,成员id:s_id,被选成员id:p_id)   id        s_id        p_id   1         a           b
   2         a           c
   3         a           d
   4         b           a
   5         b           c
   6         b           d
   7         c           a
   8         c           b
   9         c           d
  10         d           a
  11         d           b
  12         d           c
  13         e           f
  14         e           g
  15         f           e
  16         f           g
  17         g           e
  18         g           f
        ......
        ......  下面还有很多记录,而且不断的有人加进来,现在根据他们的对应关系我能得到组(a,b,c,d),(e,f,g)只要他们之间任何一方没选对方就构不成一个组,假如g没有选择f,那么e,f,g就不能组队参加活动了,现在 我要查询一下表里有哪些完整的组队,怎么实现?用存储过程也行。

解决方案 »

  1.   

    这个问题有些复杂:
    基本思路:
    通过如下的方法查找有那些组队,比如f所在的组队有那些成员:
    SELECT P_ID
      FROM T
     WHERE S_ID = 'f'
    UNION
    SELECT S_ID
      FROM T
     WHERE P_ID = 'f'
    UNION
    SELECT 'f' FROM DUAL;
    --在验证f所在的组队是否是完整的组队:如果存在数据就不是完整组队,如果不存在数据就是完整组队.
    SELECT P_ID, COUNT(*)
      FROM T
     WHERE S_ID IN (SELECT P_ID
                      FROM T
                     WHERE S_ID = 'f'
                    UNION
                    SELECT S_ID
                      FROM T
                     WHERE P_ID = 'f'
                    UNION
                    SELECT 'f' FROM DUAL)
     GROUP BY P_ID
    MINUS
    SELECT S_ID, COUNT(*)
      FROM T
     WHERE P_ID IN (SELECT P_ID
                      FROM T
                     WHERE S_ID = 'f'
                    UNION
                    SELECT S_ID
                      FROM T
                     WHERE P_ID = 'f'
                    UNION
                    SELECT 'f' FROM DUAL)
     GROUP BY S_ID;
     
      

  2.   

    建议LZ还是自已动手:
    1.编个两人互选函数(a,c;c,a);
    2.扩展互选函数(a,c,d;c,a,d;d,c,a。可拓展至十位左右大致够了吧);
    3.在存贮过程中循环记录,调用上述函数并输出。
      

  3.   

    SQL> select * from test;ID         S_ID       P_ID       TNAME
    ---------- ---------- ---------- --------------------------------------------------------------------------------
    1          a          b          
    2          a          c          
    3          a          d          
    4          b          a          
    5          b          c          
    6          b          d          
    7          c          a          
    8          c          b          
    9          c          d          
    10         d          a          
    11         d          b          
    12         d          c          
    13         e          f          
    14         e          g          
    15         f          e          
    16         f          g          
    17         g          e          
    18         g          f          18 rows selectedSQL> 
    SQL> select distinct t_group from (select s_id, wmsys.wm_concat( distinct p_id) t_group
      2    from (select s_id, p_id
      3            from test
      4          union
      5         select distinct s_id, s_id  from test
      6          )
      7   group by s_id )
      8  ;T_GROUP
    --------------------------------------------------------------------------------
    a,b,c,d
    e,f,g
      

  4.   

    飞了好大力气测试过的,已开始红色的部分没加老是得到a,b,c,d和a,c,d,b两个
    wmsys.wm_concat( distinct p_id)
    加了个distinct才得到正确结果。迷惑不解....
    思路很简单。就是插入a,a
    b,b
    c,c等再根据a,b,c,d连接每个包含的字符串再取重复值就可以了。
    请高人解析疑惑
      

  5.   

    达到题目的要求了, 值得学习呀  
    select s_id, p_id
                  from T_20081010
                union
               select distinct s_id, s_id  from T_20081010  --把自己本身加进来.
    --wmsys.wm_concat  的使用, 是我想不到的呀
      

  6.   

    再加个判断比如查询到t_group后如果发现包含的关系就过滤掉
    select t_group from () a,() b where a.t_group=b.t_group and not exists (select 1 from a,b where instr(a.t_group,b.t_group)>0)
      

  7.   

    select case (when bb.num=count(*) then  else end) from 
    t aa,
    (
    select count(*) num ,sid from t group by s_id 
    )bb where aa.p_id=bb.sid