我有一个类似于以下列的表: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 tuning advisor说使用“NOT EXISTS”代替“NOT IN”但是我得到了ORA-00920:无效的关系运算符 00920. 00000 - “无效的关系运营商”..
感谢您提供的任何帮助。
答案 0 :(得分:1)
您不能简单地将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
)
在您的具体示例中,我似乎并不认为您可以合理地重写使用NOT EXISTS
的子句。
答案 1 :(得分:0)
如果有人看到这个感谢..但是,我的DBA能够挤进我帮助这个查询..答案是让它更简单,更有效..
从中选择good_mrn(选择good_mrn,CONNECT_BY_ROOT bad_mrn,cr_date,bad_mrn
来自mrn_merge从good_mrn开始=?或bad_mrn =?
通过bad_mrn =先前的good_mrn连接,其中good_mrn不在 (从mrn_merge中选择bad_mrn)和rownum< = 1;
现在它运行效率非常高。谢谢..