2012-01-19 135 views
4

Oracle中是否有可能將條件IF語句置於WHERE子句中?如果WHERE子句中的語句

我想在今天之前過濾結束日期的所有行。如果結束日期是空的,它不應該過濾它。我試過這個:

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

但是我得到「無效的關係運算符」。

+0

沒有得到你的qw。必須有一些文件解釋。是否允許。 –

+1

可能在Oracle中重複[if(condition,then,else)](http://stackoverflow.com/questions/1428402/ifcondition-then-else-in-oracle)。還有很多與Oracle中的IF - ELSE條款有關的問題(或者更具體地說是'CASE - WHEN')... –

+0

嘗試WHEN關鍵字 – Acn

回答

9

你可以試試:

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

NVL()很好:) – Stefan

+0

是的,直到點你的數據庫管理系統在負載下會下降:-)對於小型數據庫可能無關緊要(這可能是這種情況,但是我們必須處理真正的龐然大物,因爲查詢中的每行函數必須被認真考慮)他們可能會破壞太多的表現。 – paxdiablo

+0

@paxdiablo NVL是在RDBMS引擎中實現的,它不是PL/SQL。與SQL結合的PL/SQL函數可能會破壞SQL性能。 –

1

你不能做到這一點:

SELECT discount_amount 
FROM vw_ph_discount_data 
WHERE sysdate > start_date 
AND (end_date IS EMPTY OR sysdate < end_date) 
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 

(從EMPTY改爲NULL,因爲這似乎是你是什麼之後)。

假設end_date被索引,即使它是兩個查詢,這應該尖叫。對返回的每一行進行一些額外的處理並不是一個好主意。

無論您選擇哪種方法進行調查,都需要使用真實世界的數據進行基準測試。優化的主要指示是度量,不要猜測。

+0

這不是有效的。通常會掃描目標行兩次。 –

+0

@弗洛林,不,它不會,查詢是相互排斥的。 IS/IS-NOT分離保證。我對這類東西做了大量測試,doSomeFunctionOn(Column)替代品幾乎總是更快。 – paxdiablo

+0

IS NOT EMPTY在Oracle –

1

您可以使用IF語句創建多個查詢或嘗試WHERE (end_date IS NULL OR end_date > SYSDATE)

不確定您是否應該在「end_date」上使用IS [NOT] EMPTY。請參閱IS EMPTY

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; 
+0

我的直覺說,end_date是'vw_ph_discount_data'表中的一列[ –

+0

]我想你是對的,弗洛林。無論如何,我只是想給出sp的基本概念。如果他在過程主體的開頭用一個簡單的select語句初始化end_date變量,那麼上面的代碼就可以工作。 –