2015-02-09 100 views
-3

我的表有這些列:ORA-00905:缺少關鍵字

|blo|NotionalCurrency|Notional|Premiumcurrency|Basecurrency|Termcurrency|StructureName|Basemarketprice|Termmarketpriceprecent |Termmarketprice| 

我想從這些獲得BLO,貨幣和價格。下面是我的SQL:

select blo.opt, 
    case 
    when opt.premiumcurrency is not null and opt.structurename is not null then currency = opt.premiumcurrency 
     case 
     when opt.notionalcurrency = opt.basecurrency and opt.premiumcurrency = opt.termcurrency then price = opt.termmarketpricepercent/opt.notional 
     else 
      case 
      when opt.premiumcurrency = opt.basecurrency then price = opt.basemarketprice /100 
      else 
      price = opt.termmarketpriceprecent /100 
      end 
     end 
    when price = 0 then price = 0.000001 
    end 
FROM interface opt 
WHERE opt.notionalcurrency = opt.basecurrency and opt.premiumcurrency = opt.termcurrency; 

,但我得到的錯誤:ORA-00905: missing keyword

基本上,下面的邏輯應該被用來獲取/導出SQL讓三列:BLO,貨幣及價格:

If notional currency = base currency and premium currency=term currency Then 
       Price =term market price/notional 
       currency = notional currency 
Else 
       If notional currency = premium currency then 
           Price= base market price /100 
           currency = termcurrency 
       else 
           Price=term market price percent /100 
           currency = notional 
       end if 
end if 
if price=0 then 
price=0.000001 
end if 
+4

'blo.opt'後面有一個逗號丟失 – Sathya 2015-02-09 10:07:49

+0

第二種情況是在第一種情況下,沒有其他/情況條件。另外,我認爲你沒有理由有太多的嵌套情況,請[編輯]併發布你的要求是什麼 – Sathya 2015-02-09 10:17:41

+0

編輯你的問題的方式,使現有的答案無效似乎有點粗魯。現在有人提到這個問題,現在會認爲Bonesist的答案是無關或錯誤的,除非他們檢查編輯歷史。 – 2015-02-09 11:13:01

回答

2

這裏有很多問題。將它分解一下:

case 
    when opt.premiumcurrency is not null 
    and opt.structurename is not null 

where條件,opt.premiumcurrency可以使檢查不加入任何不能爲空。

then currency = opt.premiumcurrency 

您不能在此處設置值;如Arka所示,看起來您希望這是一個在最終輸出中標記爲currency的表達式。

 case 
     when opt.notionalcurrency = opt.basecurrency 
     and opt.premiumcurrency = opt.termcurrency 
     then price = opt.termmarketpricepercent/opt.notional 

現在你要找的價格,而不是貨幣,所以這不是以前的情況子句的一部分;這意味着你現在應該有一個end as currency,。但是,您也沒有else條件,這意味着如果opt.structurename爲空,您的貨幣表達式將爲空;不清楚這是否是你想要的。

但是由於您的where子句,這兩個條件都必須是真的,這使得整個case是多餘的。再次,您需要一個表達式別名,而不是嘗試使用=設置值。

 else 
      case 
      when opt.premiumcurrency = opt.basecurrency 
      then price = opt.basemarketprice /100 
      else 
      price = opt.termmarketpriceprecent /100 
      end 
     end 

你在這裏嵌套的情況下,所以它看起來像你想轉換一個if/ELSIF /其他直接構造,而沒有考慮case語義是如何工作的。當/ end可以作爲封閉情況的一部分時,不需要嵌套的case/end。但是如上所述,第一個when的條件總是必須是真的,並且opt.premiumcurrency = opt.basecurrency也必須是真實的,所以這些都是多餘的。

when price = 0 then price = 0.000001 

這只是漂浮在那裏,所以這需要有一個外殼或解碼,或者可能是一個least()如果該值永遠不會是負的。

所以與where條件你表明,這可以簡化爲:

select opt.blo, 
    case 
    when opt.structurename is not null then opt.premiumcurrency 
    end as currency, 
    case 
    when opt.termmarketpricepercent = 0 then 0.000001 
    else opt.termmarketpricepercent/opt.notional 
    end as price 
from interface opt 
where opt.notionalcurrency = opt.basecurrency 
and opt.premiumcurrency = opt.termcurrency; 

如果where條款是暫時的,你需要一個更一般的查詢,則它仍然是簡單的比你使它:

select opt.blo, 
    case 
    when opt.premiumcurrency is not null 
     and opt.structurename is not null 
     then opt.premiumcurrency 
    end as currency, -- still no 'else' so null if structurename is null 
    decode (
     case 
     when opt.notionalcurrency = opt.basecurrency 
      and opt.premiumcurrency = opt.termcurrency 
      then opt.termmarketpricepercent/opt.notional 
     when opt.premiumcurrency = opt.basecurrency 
      then opt.basemarketprice /100 
     else opt.termmarketpricepercent /100 
     end, 0, 0.000001) as price 
from interface opt; 

(我交換blo.optopt.blo作爲沙迪亞斑點,並且還固定在至少一隻參考一個錯字...)

根據您最近的修改,您希望貨幣和價格都基於相同的條件進行挑選,而原始查詢並不明顯。每個案件只能評估一個價值,所以你需要重複兩個表達式的條件,一個是貨幣,一個是價格;如果價格爲零,您仍然想要更改價格。再次假設where被臨時:

select opt.blo, 
    case 
    when opt.notionalcurrency = opt.basecurrency 
     and opt.premiumcurrency = opt.termcurrency 
     then opt.notionalcurrency 
    when opt.notionalcurrency = opt.premiumcurrency 
     then opt.termcurrency 
    else opt.notionalcurrency 
    end as currency, 
    decode (
    case 
     when opt.notionalcurrency = opt.basecurrency 
     and opt.premiumcurrency = opt.termcurrency 
     then opt.termmarketpricepercent/opt.notional 
     when opt.notionalcurrency = opt.premiumcurrency 
     then opt.basemarketprice/100 
     else opt.termmarketpricepercent/100 
    end, 0, 0.000001) as price 
from interface opt; 

價格計算是以前一樣,貨幣表達已經改變以匹配相同的邏輯。儘管如此,您似乎已經丟失了structurename支票。還有一個潛在的假設,即沒有一個貨幣值是空的。

SQL Fiddle部分表和沒有數據,只是爲了顯示查詢沒有錯誤。

+0

非常感謝。你的代碼返回結果。隨着需求似乎發生了一些變化,我將盡快恢復。 – Drsin 2015-02-09 14:51:31

+0

偉大的答案,亞歷克斯。 – Sathya 2015-02-09 15:16:56

5

您錯過了最初的case語句中的end。只需將when price = 0 then price = 0.000001

+0

謝謝。我現在添加了它'ORA-00905:缺少關鍵字' – Drsin 2015-02-09 10:13:58

+0

@Sathya已經爲您提供了現在獲取缺少關鍵字錯誤的原因。他在評論和回答中提出了一些優秀的觀點! – Boneist 2015-02-09 10:38:57

+0

@ALL,我已經更新了邏輯應該爲我獲得所需的3列。提前致謝。 – Drsin 2015-02-09 11:35:35

1

後添加它試試這個:

SELECT opt.blo, 
     CASE 
     WHEN (opt.premiumcurrency IS NOT NULL 
      AND opt.structurename IS NOT NULL) THEN 
      currency = opt.premiumcurrency 
     END, 
     CASE 
     WHEN (opt.notionalcurrency = opt.basecurrency 
      AND opt.premiumcurrency = opt.termcurrency) THEN 
      price = opt.termmarketpricepercent/opt.notional 
     WHEN price = 0 THEN 
      price = 0.000001 
     WHEN opt.premiumcurrency = opt.basecurrency THEN 
      price = opt.basemarketprice/100 
     ELSE 
      price = opt.termmarketpriceprecent/100 
     END 
    FROM interface opt 
WHERE opt.notionalcurrency = opt.basecurrency 
    AND opt.premiumcurrency = opt.termcurrency; 
+0

謝謝。還是相同的錯誤代碼:'Ora-00905' – Drsin 2015-02-09 10:52:28

0

我對這個查詢的幾件事情:

  1. 按我的理解,選擇是你的表的別名,並獲得屬性你應該寫opt.blo而不是blo.opt。
  2. Case語句應包含值的情況下,如列名,你正在使用的case語句

我試圖修改代碼。沒有編譯,所以可能會出現語法錯誤。只需檢查它。

select opt.blo, 
    case opt.currency 
    when opt.premiumcurrency is not null and opt.structurename is not null 
    then opt.premiumcurrency 
    end as Currency, 
    case opt.price 
    when opt.notionalcurrency = opt.basecurrency and opt.premiumcurrency = opt.termcurrency then opt.termmarketpricepercent/opt.notional 
    when opt.premiumcurrency = opt.basecurrency then opt.basemarketprice /100 
    when price = 0 then price = 0.000001 
    else 
    opt.termmarketpriceprecent /100 
    end as Price, 
FROM interface opt 
WHERE opt.notionalcurrency = opt.basecurrency and opt.premiumcurrency = opt.termcurrency; 
+0

謝謝。我運行你的代碼,但是如果你還試圖在'when opt.premiumcurrency ...'條件中指定列時,我仍然會得到'case opt.currency'語法無效的'ORA-00905' – Drsin 2015-02-09 10:50:42

+0

。 – 2015-02-09 11:03:01

+0

@Alex我沒有使用任何時候的條件 – 2015-02-09 11:11:55