【问题标题】:how to add more than 1000 values with NOT IN clause如何使用 NOT IN 子句添加超过 1000 个值
【发布时间】:2012-09-22 00:37:12
【问题描述】:

我想在 NOT IN 子句中使用逗号分隔的 id。 我正在使用oracle 11g。

select * from table where ID NOT IN (1,2,3,4,...,1001,1002,...)

结果

ORA-01795: maximum number of expressions in a list is 1000

我不想使用临时表。我正在考虑这样做

select * from table1 where ID NOT IN (1,2,3,4,…,1000) AND 
ID NOT IN (1001,1002,…,2000)

还有其他更好的解决方法吗?

【问题讨论】:

  • No..id 是不可预测的。
  • 这些 ID 的值从何而来?
  • 不使用临时表的动机是什么?
  • 上述查询的 SQL 在哪里?客户端?在存储过程、函数、包中?还是别的地方?

标签: sql oracle oracle11g


【解决方案1】:

你说你不想,但是:使用临时表。这是正确的解决方案。

在 Oracle 中,查询解析的成本很高,当您将数千个标识符放入一个巨大的 SQL 块中时,您就会得到这样的结果。此外,还有ill-defined limits 的查询长度是您要达到的。另一方面,对表执行反联接... Oracle 擅长于此。将数据批量加载到表中,Oracle 也很擅长。使用临时表。

IN 限制为一千个条目是一种健全性检查。你击中它的事实意味着你正在尝试做一些疯狂的事情。

【讨论】:

  • “你击中它的事实意味着你正在尝试做一些疯狂的事情。”说得好。
  • 我基本同意您的分析,但我认为临时表是错误的解决方案。填充临时表的开销将它们排除在许多情况下。传递一个数组——一个 PL/SQL 集合——可能是一个更好的主意。
  • 如果您有超过 1000 个值,在我看来它们可能来自您数据库中的其他地方——也许是某种查询? - 我怀疑那里没有用户勤奋地输入数字 - 在这种情况下,针对该查询的反连接可能是一个合理的解决方案。
  • 我同意,但我决定不采用这种推理方式。发帖人说他有“不可预测的”“逗号分隔的 id”;他只是想知道如何绕过 1000-IN 限制,所以这就是我选择回答的全部内容。即使它们来自数据库外部,它们也可能对应于某些确实属于数据库的域概念...
【解决方案2】:

跳出问题,你能不能用这个SQL结合SQL得到1000多个ID。这是简化 SQL 的更好方法。

【讨论】:

    【解决方案3】:

    这太疯狂了。

    但你或许可以尝试从 select 中选择:

    SELECT * FROM
      (SELECT * FROM table WHERE ID NOT IN (1,2,3,4,...,1000))
    WHERE ID NOT IN (1001,1002,…,2000)
    

    根据需要制作尽可能多的关卡。

    【讨论】:

      【解决方案4】:

      使用MINUS,与`UNION相反

      SELECT * FROM TABLE
      MINUS 
      SELECT T.* FROM TABLE T,TABLE2 T2 WHERE T.ID = T2.ID
      

      这表示表 T 上的寄存器,其 ID 不在 table2 t2

      【讨论】:

        猜你喜欢
        • 2018-11-20
        • 2010-09-28
        • 2014-10-30
        • 2011-01-24
        • 1970-01-01
        • 2013-02-19
        • 2013-03-30
        • 1970-01-01
        相关资源
        最近更新 更多