2

我有一个看起来像以下列的表:bad_mrn、good_mrn、cr_date

insert into mrn_merge values ( '00000001','00000002', '20121120');
insert into mrn_merge values ( '00000002','00000003', '20121120');
insert into mrn_merge values ( '00000003','00000004', '20121120');

所以最后。
- 1 合并到 2
- 2 合并到 3
- 3 合并到 4

如果我提供 1、2、3 或 4 的输入参数,我需要一个返回 4 的查询。以下准备好的语句确实有效,但是当我的 mrn_merge 表开始有 40k 条记录时需要很长时间。

SELECT *
FROM
   (SELECT good_mrn, LEVEL
    FROM mrn_merge
    WHERE 
        (CONNECT_BY_ROOT bad_mrn =
            (SELECT bad_mrn FROM mrn_merge WHERE LEVEL =
                (SELECT MAX (LEVEL) FROM mrn_merge  START WITH good_mrn = ?
                 CONNECT BY PRIOR bad_mrn = good_mrn )
             START WITH good_mrn = ?
             CONNECT BY PRIOR bad_mrn = good_mrn)
        )  OR ( CONNECT_BY_ROOT bad_mrn = ?)
    START WITH  bad_mrn NOT IN ( SELECT good_mrn FROM mrn_merge  )
    CONNECT BY bad_mrn = PRIOR good_mrn  ORDER BY LEVEL DESC)
WHERE ROWNUM = 1 ;

sql 调优顾问说使用“不存在”代替“不存在”,但我得到 ORA-00920:无效的关系运算符 00920。00000 -“无效的关系运算符”..

感谢您提供的任何帮助。

4

2 回答 2

2

你不能简单地NOT IN换成NOT EXISTS.

NOT IN根据子查询的结果测试一列(或括在括号中的一组列),该子查询必须返回相同数量的列。

SELECT a.cols
FROM table_a a
WHERE a.id NOT IN (
  SELECT b.id
  FROM table_b b
)

或者

SELECT a.cols
FROM table_a a
WHERE (a.id, a.name) NOT IN (
  SELECT b.id, b.name
  FROM table_b b
)

NOT EXISTS测试子查询是返回零行 (TRUE) 还是一或多行 (FALSE)。通常,子查询与外部查询相关,即子查询内部的列(或列集)针对外部查询中的列(或列集)进行测试。

SELECT a.cols
FROM table_a a
WHERE NOT EXISTS (
  SELECT 1
  FROM table_b b
  WHERE b.id = a.id
)

在您的具体示例中,在我看来,您似乎无法合理地将子句重写为 use NOT EXISTS

于 2012-11-27T17:59:43.240 回答
0

如果有人看过这个谢谢..但是,我的 DBA 能够挤我来帮助这个查询..答案是让它更简单,更高效..

select good_mrn from (select good_mrn, CONNECT_BY_ROOT bad_mrn, cr_date, bad_mrn
from mrn_merge Start with good_mrn= ? or bad_mrn=?
connect by bad_mrn = prior good_mrn) where good_mrn not in
(select bad_mrn from mrn_merge) and rownum <=1;

现在它运行得非常高效。谢谢..

于 2012-11-28T14:11:00.090 回答