2015-02-09 99 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