Oracle:嵌套游标需要将所有行与所有其他行进行比较
在下面的示例中,t1有数百万行。我需要将t1中的每一行与t1中的每一行进行比较,如果找到匹配项,则在t2中插入一行。使用下面的一个简单的嵌套游标选项,处理数据的时间太长了。id是唯一的序列号,因此不会处理所有行。我只在id1Oracle:嵌套游标需要将所有行与所有其他行进行比较,oracle,cursor,Oracle,Cursor,在下面的示例中,t1有数百万行。我需要将t1中的每一行与t1中的每一行进行比较,如果找到匹配项,则在t2中插入一行。使用下面的一个简单的嵌套游标选项,处理数据的时间太长了。id是唯一的序列号,因此不会处理所有行。我只在id1
cursor c1 is select id,x,y,z from t1;
cursor c2 is select id,x,y,z from t1;
BEGIN
open c1;
loop
fetch c1 into v1_x, v1_y, v1_z;
open c2;
loop
fetch c2 into v2_x, v2_y, v2_z;
if v1_id < v2_id then
if v1_x = v2_x then
if v1_y = v2_y then
if v1_z = v2_z then
insert into t2 (id1, id2) values (v_id1, v_id2);
end if;
end if;
end if;
end if;
exit when c2%notfound;
end loop;
close c2;
exit when c1%notfound;
end loop;
close c1;
END;
光标c1是从t1中选择id、x、y、z;
光标c2是从t1中选择id、x、y、z;
开始
开c1;
环
取c1到v1_x,v1_y,v1_z;
开放c2;
环
将c2放入v2_x,v2_y,v2_z;
如果v1\u id
谢谢
Gary我会尝试不使用PL/SQL。循环是逐行处理,这是(对于大型数据集)一步一步慢慢地进行的。大型数据集的嵌套循环?自杀 这个怎么样
merge into t2 c
using (select a.id id1, a.x x1, a.y y1, a.z z1,
b.id id2, b.x x2, b.y y2, b.z z2
from t1 a join t2 b on b.id < a.id
and b.x = a.x
and b.y = a.y
and b.z = a.z
) x
on (1 = 1)
when not matched then insert (id1, id2)
values (x.id1, x.id2);
我的目标表:
SQL> create table t2
2 (id1 number, -- you have only ID1 and ...
3 id2 number, -- ... ID2
4 ename1 varchar2(10),
5 ename2 varchar2(10),
6 deptno1 number,
7 deptno2 number,
8 job1 varchar2(10),
9 job2 varchar2(10));
Table created.
SQL>
合并:
SQL> merge into t2 c
2 using (select a.empno id1, a.ename ename1, a.deptno deptno1, a.job job1,
3 b.empno id2, b.ename ename2, b.deptno deptno2, b.job job2
4 from emp a join emp b on b.empno < a.empno
5 and b.deptno = a.deptno
6 and b.job = a.job
7 ) x
8 on (1 = 1)
9 when not matched then insert (id1, id2, ename1, ename2, deptno1, deptno2, job1, job2)
10 values (x.id1, x.id2, x.ename1, x.ename2, x.deptno1, x.deptno2, x.job1, x.job2);
8 rows merged.
在我看来还可以,在我的14行样本表上运行得很快。现在,在数百万张桌子上试一试。谢谢。我要试试这个。虽然我不确定我是否理解为什么有两个不同的“b”表。“b”似乎代表t1和t2,除非我误解了什么。不客气。你说得对,我应该多注意别名。现在修好了。虽然不会对最终结果做任何“错误”的事情,但是,是的,应该编写查询,这样就不必怀疑什么是什么。我很抱歉。您已经在b.empno
SQL> merge into t2 c
2 using (select a.empno id1, a.ename ename1, a.deptno deptno1, a.job job1,
3 b.empno id2, b.ename ename2, b.deptno deptno2, b.job job2
4 from emp a join emp b on b.empno < a.empno
5 and b.deptno = a.deptno
6 and b.job = a.job
7 ) x
8 on (1 = 1)
9 when not matched then insert (id1, id2, ename1, ename2, deptno1, deptno2, job1, job2)
10 values (x.id1, x.id2, x.ename1, x.ename2, x.deptno1, x.deptno2, x.job1, x.job2);
8 rows merged.
SQL> select * from t2 order by ename1, ename2;
ID1 ID2 ENAME1 ENAME2 DEPTNO1 DEPTNO2 JOB1 JOB2
---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
7876 7369 ADAMS SMITH 20 20 CLERK CLERK -- Adams and Smith
7902 7788 FORD SCOTT 20 20 ANALYST ANALYST -- Scott and Ford
7654 7499 MARTIN ALLEN 30 30 SALESMAN SALESMAN -- Allen and Martin
7654 7521 MARTIN WARD 30 30 SALESMAN SALESMAN
7844 7499 TURNER ALLEN 30 30 SALESMAN SALESMAN -- Allen and Turner
7844 7654 TURNER MARTIN 30 30 SALESMAN SALESMAN
7844 7521 TURNER WARD 30 30 SALESMAN SALESMAN
7521 7499 WARD ALLEN 30 30 SALESMAN SALESMAN -- Allen and Ward
8 rows selected.