请教结果集内分组求交集的sql语句

[复制链接]
查看11 | 回复4 | 2005-10-30 17:05:33 | 显示全部楼层 |阅读模式
我们知道,如果有两个结果集,需要求交集的话,可以使用 INTERSECT 这个关键字,但如果是一个结果集,按照某个规则分组,然后求各组之间交集,这条sql语句,该如何写呢。脚本如下
create table t_test200(id1 varchar2(16),id2 varchar2(16),value1 varchar2(32),value2 varchar2(32),value3 varchar2(32));
--A组
insert into t_test200(id1,id2,value1,value2,value3) values('a','a','000','111','222');
insert into t_test200(id1,id2,value1,value2,value3) values('a','a','111','222','333');
insert into t_test200(id1,id2,value1,value2,value3) values('a','a','222','333','444');
--B组
insert into t_test200(id1,id2,value1,value2,value3) values('b','b','000','111','222');
insert into t_test200(id1,id2,value1,value2,value3) values('b','b','333','444','555');
insert into t_test200(id1,id2,value1,value2,value3) values('b','b','444','555','666');
--C组
insert into t_test200(id1,id2,value1,value2,value3) values('c','c','000','111','222');
insert into t_test200(id1,id2,value1,value2,value3) values('c','c','555','666','777');
insert into t_test200(id1,id2,value1,value2,value3) values('c','c','666','777','888');
--D组
insert into t_test200(id1,id2,value1,value2,value3) values('d','d','666','777','888');
insert into t_test200(id1,id2,value1,value2,value3) values('d','d','777','888','999');
insert into t_test200(id1,id2,value1,value2,value3) values('d','d','888','999','aaa');

数据如上面,按照id1和id2分组,交集取value1,value2,value3。A组∩B组∩C组,结果是'000','111','222'。C组∩D组,结果集是'666','777','888'。A组∩B组∩C组∩D组,结果集是空。
请问这条sql语句,该如何写呢?
谢谢。

回复

使用道具 举报

千问 | 2005-10-30 17:05:33 | 显示全部楼层
只要加个where条件
test=# select value1,value2,value3 from t_test200 where id1='a'
test-# intersect
test-# select value1,value2,value3 from t_test200 where id1='b'
test-# intersect
test-# select value1,value2,value3 from t_test200 where id1='c';
value1 | value2 | value3
--------+--------+--------
000| 111| 222
test=# select value1,value2,value3 from t_test200 where id1='c'
test-# intersect
test-# select value1,value2,value3 from t_test200 where id1='d';
value1 | value2 | value3
--------+--------+--------
666| 777| 888
(1 行记录)
test=# select value1,value2,value3 from t_test200 where id1='a'
test-# intersect
test-# select value1,value2,value3 from t_test200 where id1='b'
test-# intersect
test-# select value1,value2,value3 from t_test200 where id1='c'
test-# intersect
test-# select value1,value2,value3 from t_test200 where id1='d';
value1 | value2 | value3
--------+--------+--------
(0 行记录)
回复

使用道具 举报

千问 | 2005-10-30 17:05:33 | 显示全部楼层
谢谢 〇〇 大神的回复,太感谢了。
不好意思,我没有说清楚,前面的id1和id2值都不是固定的,不能直接写where id1='a' and id2='a',因为也有可能是其它的值。要根据id1和id2的值进行分组,如我题目前面的,可以根据id1和id2的值,把t_test200表数据分成A组、B组、C组、D组,如果还有其它的id1和id2的值,还可以继续分成其它的组。然后根据这些id1和id2的值,进行交(∩)操作。
现在坚守开发版的大神太少了,能得到 〇〇 大神的回复,真是太感动了。
回复

使用道具 举报

千问 | 2005-10-30 17:05:33 | 显示全部楼层
create or replace typet_obj_value as object ( value1 varchar2(32),

value2 varchar2(32),

value3 varchar2(32)

);


create or replace type nt_value is table oft_obj_value;

--这里简化一下,组,只取id1 ,求出组的两两相交
SQL>
SQL> with t as (
2select id1,cast(collect(t_obj_value(value1,value2,value3)) as nt_value) c_nt_value
3from t_test200
4 group by id1,id2
5 ),
6 m as (
7select r.id1 g1,s.id1 g2,r.c_nt_value multiset intersect s.c_nt_value nt_res
8from t r,t s
9 where r.id1 0
group by value1,value2,value3
having count(distinct id1)=3;
VALUE1
VALUE2
VALUE3
-------------------------------- -------------------------------- -----------------
000
111
222
回复

使用道具 举报

千问 | 2005-10-30 17:05:33 | 显示全部楼层
非常感谢 solomon_007 和 newkid 两位高手。
solomon_007高手的方法,我还要测试,消化一下。
我按照newkid的方法,稍微修改一下,就取count(*)最大的那条记录,暂时应该也可以满足我的需求了,我真是糊涂了。
SQL> select value1,value2,value3,count(*)
2from t_test200
3group by value1,value2,value3
4order by count(*) desc;

VALUE1VALUE2
VALUE3 COUNT(*)
------------- ----------------- -------------- ----------
000 111
222
3
666 777
888
2
111 222
333
1
555 666
777
1
333 444
555
1
444 555
666
1
888 999
aaa
1
777 888
999
1
222 333
444
1

9 rows selected
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行