2015-02-09 2 views
-3

Моя таблица имеет следующие столбцы:ORA-00905: отсутствует ключевое слово

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

Я хочу получить Бло, валюту и цену из них. Ниже мой 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, чтобы получить три колонки: Ли, валюту и цена:

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

+0

Второй случай следует за первым, без условия else/case. Кроме того, я думаю, что у вас слишком много вложенных случаев без причины, пожалуйста, отредактируйте [edit] и сообщите, какие именно ваши требования: – Sathya

+0

Редактирование вашего вопроса таким образом, чтобы недействительный существующий ответ казался грубым. Кто-то, придя к этому вопросу, теперь подумает, что ответ Bonesist не имеет значения или неправилен, если он не проверяет историю изменений. –

ответ

2

Здесь очень много проблем. Ломать его немного вниз:

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

Из условия where, opt.premiumcurrency не может быть пустым, так что проверка ничего не добавляя.

then currency = opt.premiumcurrency 

Вы не можете установить здесь значение; похоже, вы хотите, чтобы это выражение было помечено как currency в финальном выпуске, как показала Арка.

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

Теперь вы ищете цену, а не валюту, поэтому это не является частью предыдущей статьи; что означает, что вы должны были иметь end as currency,. Но у вас также нет условия else, что означает, что ваше выражение в валюте будет равно null, если opt.structurename имеет значение NULL; неясно, если это то, что вы хотите.

Но все эти условия должны быть истинными из-за вашего предложения where, что делает весь этот case избыточным. И снова вам нужен псевдоним выражения, а не пытаться установить значение с =.

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

Вы вложенный случай вот так это выглядит, как вы пытаетесь преобразовать, если/ELSIF/еще построить непосредственно, без рассмотрения, как семантика 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.opt на opt.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

+0

Отличный ответ, Алекс. – Sathya

5

Вам не хватает end из первоначального оператора case. Просто добавьте его после when price = 0 then price = 0.000001

+0

Спасибо. Я добавил его теперь, я получаю 'ORA-00905: missing keyword' – Drsin

+0

@ Сатья уже предоставила вам причину, по которой вы теперь получаете недостающую ошибку ключевого слова. Он поднимает некоторые замечательные моменты в своих комментариях и ответах! – Boneist

+0

@ALL, я обновил, какая логика должна быть для меня, чтобы получить необходимые 3 столбца, которые мне нужны. заранее спасибо. – Drsin

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

0

У меня есть несколько вещей об этом запросе:

  1. Согласно моему пониманию, выбирают это имя псевдоним вашей таблицы и получить атрибут вы должны написать opt.blo not blo.opt.
  2. Дело заявление должно содержать случай значение, как имя столбца, где вы используете случай о

Я попытался изменить код. Не скомпилирован, поэтому может возникнуть синтаксическая ошибка. Просто проверьте это.

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

Спасибо. Я запускаю ваш код, но я все равно получаю 'ORA-00905' – Drsin

+0

' case opt.currency' является недопустимым синтаксисом, если вы также пытаетесь указать столбец в состоянии 'when opt.premiumcurrency ...'. –

+0

@Alex Я не использовал имя столбца где бы то ни было, когда условие –