Oracle SQL:如何在IN子句中使用1000多个项

Oracle SQL:如何在IN子句中使用1000多个项,sql,oracle,Sql,Oracle,我有一个SQL语句,我想通过使用IN子句中的来获取1200个ep_代码的数据。当我在IN子句中包含超过1000个ep_代码时,Oracle说我不允许这样做。为了克服这一问题,我尝试如下更改SQL代码: SELECT period, ... FROM my_view WHERE period = '200912' ... AND ep_codes IN (...1000 ep_codes...) OR ep_codes IN (...200 ep_

我有一个SQL语句,我想通过使用
IN
子句中的
来获取1200个
ep_代码的数据。当我在IN子句中包含超过1000个
ep_代码时,Oracle说我不允许这样做。为了克服这一问题,我尝试如下更改SQL代码:

SELECT period, ...
FROM   my_view
WHERE  period = '200912'
       ...
       AND ep_codes IN (...1000 ep_codes...)
       OR  ep_codes IN (...200 ep_codes...)
代码成功地执行了,但结果很奇怪(所有时段都会获取计算结果,而不仅仅是200912,这不是我想要的)。在
子句中使用
之间的
是否合适,或者我应该执行两个单独的代码,一个是1000代码,另一个是200 ep_代码



帕斯卡·马丁的解决方案非常有效。感谢所有提供宝贵建议的人。

事实上,我不确定在
in()
中使用这么多值有多好——特别是在性能方面

当你说“结果很奇怪”时,可能是因为括号有问题?如果你尝试一下这个,而不是你的建议:

SELECT ...
FROM ...
WHERE ...
      AND (
          ep_codes IN (...1000 ep_codes...)
          OR  ep_codes IN (...200 ep_codes...)
      )

它是否会使结果不那么奇怪?

在Oracle中处理此问题的推荐方法是创建一个临时表,将值写入其中,然后连接到此表。在
子句中使用动态创建的
,意味着查询优化器对每个查询进行“硬解析”

create global temporary table LOOKUP
(
    ID NUMBER
) on commit delete rows;

-- Do a batch insert from your application to populate this table
insert into lookup(id) values (?)

-- join to it
select foo from bar where code in (select id from lookup)

从性能和可维护性来看,将代码放在一个单独的表中似乎是一个更好的主意

SELECT ...
FROM ...
WHERE ...
   AND ep_code in (select code from ep_code_table)

您是否可以将1200
ep_code
值插入临时表,然后将
内部联接
插入该表以过滤行

SELECT a.*
FROM mytable a
INNER JOIN tmp ON (tmp.ep_code = a.ep_code)
WHERE ...

实际上,您可以在这里使用集合/多集合。您需要一个数字表类型来存储它们

CREATE TYPE NUMBER_TABLE AS TABLE OF NUMBER;
...
SELECT *
FROM my_view
WHERE period MEMBER OF NUMBER_TABLE(1,2,3...10000)

阅读更多有关Multiset的信息:

我更新了问题,以澄清奇怪的结果。现在,我正在尝试您建议的代码(带有额外的括号)。一拿到结果,我就告诉你。谢谢,现在一切正常。我再一次明白了额外的括号是多么重要。不客气:-)-是的,括号会很有帮助;-)我不确定。我正在使用它为我提供的一些视图。我们最近将一些代码从使用“in”改为使用临时查找表。对于某些查询,性能从几分钟到一秒钟内都有了显著的提高。但这是对服务器的多个并行请求的有效实现吗?据我所知,Oracle server上可能有多个打开的事务,正在尝试创建
查找
table@Ilya:见。对于“提交删除行”,数据应该只在事务范围内可见。@retronym:有趣的答案,我在我们的项目中尝试过。但是我花了很多时间。我可能在数据插入方面出错。也就是说,我有大约2500个值,应该插入到临时表中。您能否建议如何将这些值正确插入到oracle DB中?这在语法上非常优雅,但性能令人失望。使用此语法选择单个主键值时,CBO会选择索引快速完全扫描。使用数千个ID和中等大小的表(40K行)进行测试,它仍然比在临时表上加入快约3倍(由于散列连接)。这并不包括创建和填充临时表的时间。