SQL IN 子句 1000 项限制

Posted

技术标签:

【中文标题】SQL IN 子句 1000 项限制【英文标题】:SQL IN Clause 1000 item limit 【发布时间】:2011-06-10 23:15:30 【问题描述】:

可以在 SQL IN 子句中放置超过 1000 个项目吗?我们一直遇到无法处理 Oracle 数据库的问题。

如果是,我们如何在 SQL IN 子句中放入 1000 多个项目?

如果没有,我还能做什么?

【问题讨论】:

Oracle SQL: How to use more than 1000 items inside an IN clause 的可能重复项 除了重复之外,我想让您知道存在 in 子句限制是有原因的。它是一个资源极其密集的查询。你应该按照@Jonathan 所说的去做。 How to put more than 1000 values into an Oracle IN clause的可能重复 【参考方案1】:

如果你没有创建临时表的奢侈,你可以使用 WITH 子句来模拟它

with t as (
  select 1 val from dual 
  union all select 2 from dual
  union all select 3 from dual
    ...
  union all select 5001 from dual
  union all select 5002 from dual
)
select * 
  from mytable
 where col1 in (select val from t)

显然,您也可以将 mytable 加入 t

我最喜欢 Gordy 的回答,只是展示了另一种方式。

【讨论】:

【参考方案2】:

对于同一个变量,我们可以有多个“IN”语句。

例如:

select val
 from table
where val in (1,2,3,...)
or
val in (7,8,9,....)

【讨论】:

【参考方案3】:

另一种方式:

SELECT COL1, COL2, COL3 FROM YOUR_TABLE
WHERE 1=1
AND COL2 IN (
SELECT VAL1 as FAKE FROM DUAL
UNION
SELECT VAL2 as FAKE FROM DUAL
UNION
SELECT VAL3 as FAKE FROM DUAL
--...
)

【讨论】:

您应该使用UNION ALL 而不是UNIONVALUES 构造函数而不是两者。 这个答案已经很老了——改用VALUES表构造函数 @Hogan Oracle 直到 21c 才将 values 列为表构造函数。你能分享文档的链接吗? @astentx -- 你必须在 oracle 中使用 UNION ALL @hogan 是的,这个答案是关于这个的,但是你的评论建议使用 5 年前和半年前的 values【参考方案4】:

还有另一种解决方法,在任何其他答案(或其他已回答的问题)中都没有提到:

任何像x in (1,2,3) 这样的in 语句都可以重写为(1,x) in ((1,1), (1,2), (1,3)),并且1000 个元素的限制将不再适用。我在x 上使用索引进行了测试,解释计划仍然报告Oracle 正在使用访问谓词和范围扫描。

【讨论】:

+1 很酷的技巧 :) - 使用 10,001 个元素进行测试 - 虽然性能似乎受到影响 @Nitish 我的猜测是对元组的支持是后来才出现的,那时开发人员对 ZOI 原则有了启发 有人知道如何使用 JPA 查询语言来实现吗? @JeffreyKemp Oracle 似乎将元组样式 in 子句限制为 70,000,仍然比常规 in 子句限制更好。 也许你的意思是 65535,@JeffreyKemp。 asktom.oracle.com/pls/apex/…,最后评论。 “我测试过,元组列表的限制是 65,535 - 正如您在示例中所暗示的那样。与您的 Oracle 版本相同,12.2.0.1 ......只需将原子元素包装成 1 元组括号不起作用;元组必须是 n >= 2 的 n 元组。 .... 对于此类复合条件,Oracle 的硬限制为 2^16 - 1 = 65,535 个组件条件 - 无论这些条件是什么是”【参考方案5】:

您应该将 IN 子句转换为 INNER JOIN 子句。

您可以像这样转换查询

SELECT  foo   
FROM    bar   
WHERE bar.stuff IN  
       (SELECT  stuff FROM asdf)

在另一个类似的查询中。

SELECT  b.foo 
FROM    ( 
        SELECT  DISTINCT stuff 
        FROM    asdf ) a 
JOIN    bar b 
ON      b.stuff = a.stuff

你也会获得很多的表现

【讨论】:

以上是关于SQL IN 子句 1000 项限制的主要内容,如果未能解决你的问题,请参考以下文章

Informix:IN 子句中的项目数量限制?

linqpad - 大 NOT IN 子句超出限制 - 还有其他方式吗? - Linq to SQL

SQL IN 逗号分隔参数与内部查询

如何将超过 1000 个值放入 Oracle IN 子句 [重复]

MongoDB 的 $in 子句是不是有参数数量的最大限制

MongoDB 的 $in 子句是不是有参数数量的最大限制