Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle:嵌套游标需要将所有行与所有其他行进行比较_Oracle_Cursor - Fatal编程技术网

Oracle:嵌套游标需要将所有行与所有其他行进行比较

Oracle:嵌套游标需要将所有行与所有其他行进行比较,oracle,cursor,Oracle,Cursor,在下面的示例中,t1有数百万行。我需要将t1中的每一行与t1中的每一行进行比较,如果找到匹配项,则在t2中插入一行。使用下面的一个简单的嵌套游标选项,处理数据的时间太长了。id是唯一的序列号,因此不会处理所有行。我只在id1

在下面的示例中,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.empnoSQL> 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.