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;
关于这个查询我有几点看法:
- 根据我的理解,opt 是您的 table 的别名,要获取属性,您应该写 opt.blo 而不是 blo.opt。
- 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.
我的 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;
关于这个查询我有几点看法:
- 根据我的理解,opt 是您的 table 的别名,要获取属性,您应该写 opt.blo 而不是 blo.opt。
- 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.