Oracle WHERE子句中的If语句

Oracle WHERE子句中的If语句,oracle,Oracle,在Oracle中,是否可以将条件IF语句放在WHERE子句中 我想筛选结束日期在今天之前的所有行。如果结束日期为空,则不应对其进行过滤。我试过这个: SELECT discount_amount FROM vw_ph_discount_data WHERE sysdate > start_date AND IF end_date IS NOT EMPTY THEN sysdate < end_date 但我得到了无效的关系运

在Oracle中,是否可以将条件IF语句放在WHERE子句中

我想筛选结束日期在今天之前的所有行。如果结束日期为空,则不应对其进行过滤。我试过这个:

SELECT discount_amount 
FROM vw_ph_discount_data 
WHERE sysdate > start_date
AND
    IF 
        end_date IS NOT EMPTY 
    THEN 
        sysdate < end_date
但我得到了无效的关系运算符

您可以尝试:

SELECT discount_amount 
FROM vw_ph_discount_data 
WHERE sysdate > start_date
AND sysdate < nvl(end_date,sysdate+1)
你不能这样做吗:

SELECT discount_amount 
FROM vw_ph_discount_data 
WHERE sysdate > start_date
AND (end_date IS EMPTY OR sysdate < end_date)

即使有可能,这也不是一个好主意。每行函数将破坏性能

在这种情况下,最好的方法可能是合并两个排他查询:

SELECT discount_amount 
    FROM vw_ph_discount_data 
    WHERE sysdate > start_date
    AND   end_date IS NULL
UNION ALL
SELECT discount_amount 
    FROM vw_ph_discount_data 
    WHERE sysdate > start_date
    AND   end_date IS NOT NULL
    AND   sysdate < end_date
从空更改为空,因为这似乎是您所追求的

假设end_date被编入索引,即使是两个查询,也应该会发出尖叫声。必须对返回的每一行进行额外的处理很少是一个好主意

无论您选择何种方法进行调查,都要用真实世界的数据对其进行基准测试。优化的主要指令是measure,不要猜测。

您可以使用IF语句创建多个查询,或者在end\u date为NULL或end\u date>SYSDATE时尝试


不确定是否应使用结束日期时为[非]空。请参阅。

我认为纯Sql代码中不能使用if-else语句。您需要使用存储过程来实现您的目标。我想在您的情况下,您可以使用以下代码:

DECLARE
  DATE end_date
BEGIN
  IF end_date IS NOT NULL THEN
    SELECT discount_amount 
    FROM vw_ph_discount_data 
    WHERE sysdate > start_date AND sysdate < end_date;
  END IF;
END;

没有拿到你的qw。一定有一些文件对此进行了解释。是否允许。的可能副本。在Oracle中,还有很多与IF-ELSE子句或更具体的CASE-WHEN相关的问题……这是没有效率的。通常会扫描目标行两次。@Florin,不,不会,查询是互斥的。IS/IS-NOT分离保证:。我已经对这类东西做了大量测试,doSomeFunctionOnColumn alternatives.IS NOT EMPTY在中无效几乎总是更快Oracle@Florin,请发送您正在吸烟的内容:使用IS[NOT]EMPTY条件测试指定的嵌套表是否为空。它不涉及列值。是的,直到您的DBMS在负载下崩溃为止:-对于小型数据库可能并不重要,这可能是事实,但我们必须处理真正的庞然大物,查询中的每行函数必须经过严格的验证,否则会破坏太多的性能。@paxdiablo NVL是在RDBMS引擎中实现的,而不是PL/SQL。PL/SQL函数与SQL相结合会破坏SQL性能。不,任何必须获取大量记录,然后修改其中一列的查询都会破坏性能。这包括NVL、COALESCE和所有这些东西。在过程的早期,比如在where过滤器中,减少查询的基数几乎总是更好的。我想我们现在可能已经讨论到了极点-评论部分开始警告我关于扩展的讨论。我的直觉是,结束日期是表vw_ph_折扣数据中的一列我想你是对的,弗洛林。我只是想给出sp的基本概念。如果他在过程体的开头用一个简单的select语句初始化end_date变量,那么上面的代码就可以工作了。