如果是WHERE子句中的语句

时间:2012-01-19 08:13:30

标签: oracle

在Oracle中是否可以在WHERE子句中放置条件IF语句?

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

SELECT discount_amount 
FROM vw_ph_discount_data 
WHERE sysdate > start_date
AND
    IF 
        end_date IS NOT EMPTY 
    THEN 
        sysdate < end_date

但我得到“无效的关系运营商”。

5 个答案:

答案 0 :(得分:9)

您可以尝试:

SELECT discount_amount 
FROM vw_ph_discount_data 
WHERE sysdate > start_date
AND sysdate < nvl(end_date,sysdate+1)

答案 1 :(得分:3)

即使有可能,也不是一个好主意。每行功能会破坏性能。

在这种情况下,最好的方法是将两个独占查询联合起来:

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

(从NULL更改为EMPTY,因为这似乎就是您所追求的。)

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

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

答案 2 :(得分:3)

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

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;

答案 3 :(得分:1)

你不能这样做:

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

答案 4 :(得分:1)

您可以使用IF语句创建多个查询或尝试WHERE (end_date IS NULL OR end_date > SYSDATE)

不确定是否应在“end_date”上使用IS [NOT] EMPTY。请参阅IS EMPTY