我想根据相关表中的行比较两个记录。假设我有两个表,FOOS和BARS。
FOOS
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
+----+
BARS
+--------+-------+
| foo_id | value |
+--------+-------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 3 | 3 |
+--------+-------+
所以每个Foo都有一组酒吧。
我希望能够从FOO ID中找出其他FOOS具有相同ID的情况。
我想将结果显示为这样的表:
+---------+----------+
| src_foo | targ_foo |
+---------+----------+
| 2 | 1 |
| 3 | 1 |
+---------+----------+
以下是提供上述数据的数据库设置脚本:
create table foos (id number(32) not null) ;
create table bars (foo_id number(32) not null, val number(32) not null);
insert into foos (id) values (1);
insert into foos (id) values (2);
insert into foos (id) values (3);
insert into bars (val, foo_id) values (1, 1);
insert into bars (val, foo_id) values (2, 1);
insert into bars (val, foo_id) values (3, 1);
insert into bars (val, foo_id) values (1, 2);
insert into bars (val, foo_id) values (2, 2);
insert into bars (val, foo_id) values (3, 3);
答案 0 :(得分:3)
我们可以使用MULTISET
运算符和COLLECT
函数来做到这一点。
创建一个嵌套表TYPE
。
CREATE OR REPLACE TYPE numtab as TABLE OF NUMBER(32);
修改
我们可以对嵌套表使用SUBMULTISET
运算符,该运算符更简单,并且与以下方法相同。谢谢@mathguy
WITH t AS (
SELECT foo_id,
CAST(COLLECT(val) AS numtab) x
FROM bars
GROUP BY foo_id
)
SELECT a.foo_id a_foo_id,
b.foo_id b_foo_id
FROM t a
CROSS JOIN t b
WHERE a.x != b.x
AND a.x SUBMULTISET OF b.x
另一种方法
WITH t AS (
SELECT foo_id,
CAST(COLLECT(val) AS numtab) x
FROM bars
GROUP BY foo_id
)
select a_foo_id,b_foo_id FROM
( SELECT a.foo_id a_foo_id,
b.foo_id b_foo_id,
a.x a_x,
b.x b_x,
a.x MULTISET INTERSECT b.x as i
FROM t a
CROSS JOIN t b
WHERE a.x != b.x
) where i = a_x
;
答案 1 :(得分:2)
这是不使用嵌套表的替代方法:
SELECT src_foo, targ_foo
FROM (SELECT b1.foo_id targ_foo, b2.foo_id src_foo, b2.foo_id_val_count
FROM bars b1
INNER JOIN (SELECT foo_id, value, count(*) OVER (PARTITION BY foo_id) foo_id_val_count FROM bars) b2 ON b1.foo_id != b2.foo_id AND b1.value = b2.value)
GROUP BY src_foo, targ_foo, foo_id_val_count
HAVING foo_id_val_count = COUNT(*)
ORDER BY src_foo, targ_foo;
演示:https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=d1124734edcb943c0cc8b1166bd9f03f
通过首先找出每个foo_id有多少行,然后将每个foo_id与其他val_id相同的foo_id进行比较来进行工作。
如果返回的行数与该foo_id的行数相同,则您知道所有val都存在于该foo_id中。如果没有,那么我们就不在乎它们。
这是否比嵌套表解决方案要快,取决于您来查找数据等。