ORA-00905: 缺少关键字

ORA-00905: missing keyword

我的 table 有这些列:

|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

基本上,应该使用下面的逻辑来get/derive 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

您遗漏了初始 case 语句中的 end。只需在 when price = 0 then price = 0.000001

之后添加它

试试这个:

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;

关于这个查询我有几点看法:

  1. 根据我的理解,opt 是您的 table 的别名,要获取属性,您应该写 opt.blo 而不是 blo.opt。
  2. Case 语句应包含 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;

这里有很多问题。分解一下:

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

根据 where 条件,opt.premiumcurrency 不能为空,因此检查不会添加任何内容。

  then currency = opt.premiumcurrency

您不能在此处设置值;看起来您希望这是一个在最终输出中标记为 currency 的表达式,如 Arka 所示。

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

现在你要找的是价格,而不是货币,所以这不是前面 case 子句的一部分;这意味着你现在应该有一个 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/else 构造,而没有考虑 case 的语义实际如何工作。不需要嵌套的 case/end 因为这个 when/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.opt 换成 opt.blo,正如 Sathya 发现的那样,并且还修复了至少一个列参考中的拼写错误...)

根据您最近的编辑,您希望根据相同的条件选择货币和价格,这在原始查询中并不明显。每个 case 只能求出一个值,所以你需要在两个表达式中重复条件,一个用于货币,一个用于价格;如果价格为零,您仍然想更改价格。再次假设 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 检查。并且有一个潜在的假设,即 none 的货币价值实际上是空的。

SQL Fiddle with partial table and no data, just to show the queries don't error.