【问题标题】:NOT EXISTS invalid relational operatorNOT EXISTS 无效的关系运算符
【发布时间】:2012-11-15 04:15:11
【问题描述】:

我有一个类似于以下列的表: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 调优顾问说要使用“NOT EXISTS”代替“NOT IN”,但我得到 ORA-00920:无效的关系运算符 00920. 00000 - “无效的关系运算符”..

感谢您提供的任何帮助。

【问题讨论】:

  • 如果您在相当不错的 Oracle (>= 10g) 上运行,您可以研究 MODEL 子句 docs.oracle.com/cd/E11882_01/server.112/e25554/…
  • 示例 INSERT 中列的顺序是什么? bad_mrn、good_mrn 还是 good_mrn、bad_mrn? (在插入语句中指定列是一个非常不好的习惯)
  • 我在 java 中做了一个递归方法,但我想改变它让数据库为我完成工作。我对 pl/sql 一无所知,我需要努力发展这项技能..

标签: sql oracle


【解决方案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

【讨论】:

    【解决方案2】:

    如果有人看过这个,谢谢。但是,我的 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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-17
      • 2018-08-07
      • 1970-01-01
      • 2020-09-03
      • 2014-03-25
      • 1970-01-01
      • 2015-10-13
      相关资源
      最近更新 更多