有一个这样的需求:
网站要实现联合行动功能,就是要进入某项活动需要组队才能一起,比如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就不能组队参加活动了,现在 我要查询一下表里有哪些完整的组队,怎么实现?用存储过程也行。
网站要实现联合行动功能,就是要进入某项活动需要组队才能一起,比如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就不能组队参加活动了,现在 我要查询一下表里有哪些完整的组队,怎么实现?用存储过程也行。
基本思路:
通过如下的方法查找有那些组队,比如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;
1.编个两人互选函数(a,c;c,a);
2.扩展互选函数(a,c,d;c,a,d;d,c,a。可拓展至十位左右大致够了吧);
3.在存贮过程中循环记录,调用上述函数并输出。
---------- ---------- ---------- --------------------------------------------------------------------------------
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
wmsys.wm_concat( distinct p_id)
加了个distinct才得到正确结果。迷惑不解....
思路很简单。就是插入a,a
b,b
c,c等再根据a,b,c,d连接每个包含的字符串再取重复值就可以了。
请高人解析疑惑
select s_id, p_id
from T_20081010
union
select distinct s_id, s_id from T_20081010 --把自己本身加进来.
--wmsys.wm_concat 的使用, 是我想不到的呀
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)
t aa,
(
select count(*) num ,sid from t group by s_id
)bb where aa.p_id=bb.sid