在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
但我得到“无效的关系运营商”。
答案 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。