评估 Oracle IN 子句中的多个范围

Posted

技术标签:

【中文标题】评估 Oracle IN 子句中的多个范围【英文标题】:Evaluating multiple ranges within an Oracle IN clause 【发布时间】:2012-08-09 19:56:15 【问题描述】:

我有一个如下所示的 Oracle 选择:

SELECT *
  FROM CUSTOMER
 WHERE (CUSTOMER_TYPE BETWEEN 100 AND 200
     OR CUSTOMER_TYPE = 350
     OR CUSTOMER_TYPE BETWEEN 410 AND 520);

我想将其更改为在同一语句中结合多个范围和单个值的评估的东西。以下语法不正确,但是否有一些 Oracle 等价物?

SELECT *
  FROM CUSTOMER
 WHERE CUSTOMER_TYPE IN (100..200, 350, 410..520);

【问题讨论】:

为什么要这么做?您希望在这里获得什么? 嗯...据我所知,您已经在最佳状态下执行此操作。为什么要改变? 我认为作者希望在字符串中同时包含单个数字和数字范围,因此可以从变量(或文件)中读取它。 【参考方案1】:

认为这是一种可能性。

SELECT *
FROM CUSTOMER c,
(
    select level + 99 n from dual connect by level < 102
        union all
    select 350 n from dual
        union all
    select level + 409 n from dual connect by level < 112
) t
WHERE c.CUSTOMER_TYPE = t.n

它避免了 ORIN。如果你幸运的话,一个散列连接就是结果。

【讨论】:

这是一种同样准确的方法,但我看不到好处。您仍在执行相同的索引范围扫描(假设它已编入索引),但您在 SQL 中而不是在内部生成范围,这会更慢。 我试图避免 BETWEEN,因为如果我正在评估一个非连续的数字范围,它需要多个 OR 语句。我只想知道是否有一种更简单的“速记”方法来评估一系列数字。其他语言允许“100..200”作为“100 到 200 之间”的简写。我的实际查询要大得多,有许多 BETWEEN/OR 语句。 Dose Oracle 有一个等效的 BETWEEN 简写 @GreggFeldt,无论您做什么,无论如何您都需要来自多个范围的数据。这反过来意味着您必须使用逻辑 OR。无论您使用哪种语言,它仍然是相同的。为什么语法很重要?您当前的查询是否不够高效? 这不是效率问题,只是在评估多个范围时易于编写。我得出的结论是,我必须坚持 BETWEEN/OR。

以上是关于评估 Oracle IN 子句中的多个范围的主要内容,如果未能解决你的问题,请参考以下文章

SQL IN 子句保证评估为假

JOIN 子句中的 MySQL 逻辑评估是不是延迟/短路?

Oracle 字符串内容评估为标识符

SQL 编译错误:无法评估不受支持的子查询类型 - SELECT 子句中的函数调用

CASE THEN 子句总是被评估

使用 Oracle,我如何使用带有多个数组的 IN 子句?