日期:2014-05-18  浏览次数:20446 次

求一sql,去掉重复的group
现有源表如下
***************************
ColumnA   ColumnB
Group1   Key1
Group1   Key2
Group1   Key3
Group2   Key2
Group2   Key4
Group2   Key5
Group3   Key1
Group3   Key2
Group3   Key3
...
***************************
注:Key的数量位置
一个Group中有多个Key,   一个Key也能属于多个Group,一个多对多关系的表.

最后的要求是生成一张表,表明Group和Key的关系,如果多个Group下的Key相同,那么在表中只要求列出一次就可以了.(比如上表中的Group1和Group3)
***************************
ColumnC   ColumnD
1   Key1
1   Key2
1   Key3
2   Key2
2   Key4
2   Key5
***************************
如果两个group的key的数量,值都是一样,这两个group被认为是相同的group,需要去重复

------解决方案--------------------
奇怪...一模一樣的問題??

http://community.csdn.net/Expert/topic/5336/5336113.xml?temp=.797619
------解决方案--------------------
针对楼主提出的问题,要求去除结果中相等的GROUP(GROUP相等的定义:GROUP对应的KEY集合相等视为GROUP相等),提出解决方案如下:
1,根据GROUP得到对应的KEY集合;
2,比较这些KEY集合是否相等;
3,把两个相等的GROUP保留一个;
经过这样三个步骤就可以得到要求的结果了,
具体过程如下(ORACLE PL/SQL描述):
建表:
create table GROUP_COLUMN
(
GRO NUMBER not null,
COL NUMBER not null,
PRIMARY KEY(GRO,COL)
);
建集合比较函数:
CREATE OR REPLACE FUNCTION F_SET_COMPARE(PARA1 IN NUMBER, PARA2 IN NUMBER)
RETURN INTEGER IS
RESULT INTEGER;
COMPARE1 LONG;
COMPARE2 LONG;
BEGIN
SELECT COUNT(*)
INTO COMPARE1
FROM ((SELECT COL FROM GROUP_COLUMN WHERE GRO = PARA1) MINUS
(SELECT COL FROM GROUP_COLUMN WHERE GRO = PARA2));

SELECT COUNT(*)
INTO COMPARE2
FROM ((SELECT COL FROM GROUP_COLUMN WHERE GRO = PARA2) MINUS
(SELECT COL FROM GROUP_COLUMN WHERE GRO = PARA1));

IF COMPARE1 = COMPARE2 AND COMPARE1 = 0 THEN
RESULT := 0; /*表示得到的集合相等*/
ELSE
RESULT := 1; /*表示得到的集合不相等*/
END IF;

RETURN(RESULT);
END F_SET_COMPARE;
建大小比较函数(中间会用到,用于标识出重复列):
CREATE OR REPLACE FUNCTION F_GET_MIN(PARA1 IN NUMBER, PARA2 IN NUMBER)
RETURN NUMBER IS
RESULT NUMBER;
BEGIN
IF PARA1 > PARA2 THEN
RESULT := PARA2;
END IF;
RETURN(RESULT);
END F_GET_MIN;
最终使用如下SQL可以查询出想要的结果:
SELECT *
FROM GROUP_COLUMN
WHERE GRO NOT IN
(SELECT GRO
FROM (SELECT DISTINCT A.GRO, F_GET_MIN(A.GRO, B.GRO)
FROM (SELECT GRO FROM GROUP_COLUMN) A,
(SELECT GRO FROM GROUP_COLUMN) B
WHERE A.GRO <> B.GRO
AND F_SET_COMPARE(A.GRO, B.GRO) = 0
AND NOT F_GET_MIN(A.GRO, B.GRO) IS NULL));