Всем привет! 🙂
Да уж, давно не писал в блог, начну сейчас исправляться! Сначала отпуск был продолжительный, а потом еще и заболел, все это отодвигало публикацию новых статей.
В этой статье я хочу написать про функцию sql, которая доступна только в СУБД Oracle. Функция называется «DECODE», представляющая собой упрощенный вариант выражения «CASE WHEN»:
DECODE (<Контрольное значение>, <Значение1>, <Значение2>, <Значение3>, <Значение4>…<Дефолтное значение>)
Здесь, «Контрольное значение» — это значение, которое проверяется.
Т.е. это эквивалентно этому:
CASE <контрольное значение> WHEN <значение1> THEN <значение2> WHEN <значение3> THEN <значение4> ... ELSE <последнее значение> END |
Задача программиста — правильно соотнести пары значений после первоначальной переменной, т.е. «<Контрольного значения>».
Приведу очень примитивный пример:
SELECT decode ('Вова1' , '8', 'Вова' , 'Вова', 'Вова4' , 'Дима') FROM dual |
Что вернет этот запрос!? А он вернет ответ «Дима», а без значения «Дима», вернет NULL. Т.к. здесь значение «Дима» — это дефолтное и есть значение, т.е. которое возвращается по умолчанию.
Хотел сделать одно замечание — эта функция достаточно сложна для понимания и её использование может привести к ошибкам в запросах, поэтому лучше использовать другие похожие функции — Nvl и Coalesce. Чаще всего именно с помощью них можно решить нужные задачи в обработке null-значений без помощи функции Decode.
Если что-то будет непонятно, пишите в комментариях, всегда попробую помочь 🙂
Update — Спасибо всем, кто нашел ошибку в тексте данной статьи, невнимательно некоторые вещи написал, поздно было, спал видимо 🙂
Удачи!
Всем привет, decode и case работают по разному с значением NULL
select decode(», null, ‘NULL’, ‘NOT_NULL’) DCD,
case » when null then ‘NULL’ else ‘NOT_NULL’ end CS
from dual
decode вернет NULL
case вернет NOT_NULL
Верно, нужно аккуратно и в нужное время использовать свое.
спасибо вам! оч помогли с описанием работы функции 🙂
Хорошо, что смог помочь =)
Есть запрос: select DISTINCT o.code КОД, o.short_name ЛПУ, decode(pd.period_id,1,’+’,null) янв, decode(pd.period_id,2,’+’,null) фев,
decode(pd.period_id,3,’+’,null) мар, decode(pd.period_id,4,’+’,null) апр, decode(pd.period_id,5,’+’,null) май, decode(pd.period_id,6,’+’,null) июн, decode(pd.period_id,7,’+’,null) июл, decode(pd.period_id,8,’+’,null) авг, decode(pd.period_id,9,’+’,null) сен, decode(pd.period_id,10,’+’,null) окт, decode(pd.period_id,11,’+’,null) ноя,
decode(pd.period_id,12,’+’,null) дек
from n840.med_orgs o
inner join plan p on (o.id=p.MED_ORG_ID)
inner join plan_distr pd on (pd.plan_id=p.id)
Он возвращает 3 строки( так как в 3 месяцах стоят крестики). Но необходимо возвращать одну строку с крестиками в соответствующем месяце… Это реально?
С каких пор DECODE стала функцией. На мой взгляд это все же выражение!
В оф. доке это как раз функция и есть — «In a DECODE function, Oracle considers two nulls to be equivalent». =)
было б хорошо, если в описании присутсвтовали типы, с которыми можно сравнивать и возвращать
Типы могут быть такие (большинство распространенных) — NUMBER, BINARY_FLOAT, or BINARY_DOUBLE, CHAR, VARCHAR2, NCHAR, or NVARCHAR2 =)