
Функция decode
Функция DECODE выполняет ту же функцию, что и CASE, единственным отличием является ее синтаксис. Надо отметить, что исторически функция DECODE в SQL намного старше, но ORACLE, в виду более легкой читаемости CASE, ввел также данную конструкцию в свой SQL.
DECODE (expression, search_1, result_1, Search _ 2, result_2, ……search_n, result_n, default), где
expression – это то выражение, которое сравнивается с search1, если оно совпадает, то выходит результат result1. Иначе идет вторая проверка и так далее до n-ой проверки. В конце в случаи всех неудачных проверок в результате выйдет default.
ПРИМЕР:
Напишите запрос, который возвращает информацию об имени, фамилии и должности сотрудников (столбец JOB_ID) на основе таблицы. При этом:
-
если в столбце JOB_ID для сотрудников находится значение SA_REP, то должно выводиться «Торговый представитель»;
-
если в столбце JOB_ID для сотрудников находится значение SA_MAN, то должно выводиться «Менеджер по продажам»;
-
если в этом столбце находится любое другое значение, то должно выводиться «Другое».
SELECT first_name AS «Имя», last_name As «Фамилия», DECODE (JOB_ID, 'SA_REP', 'Торговый представитель', 'SA_MAN', 'Менеджер по продажам', 'Другое') AS «Должность» FROM hr.employees.
Выполнение работы
--А)текущая дата и дата двухнедельной давности
SELECT SYSDATE AS "today",SYSDATE-14 AS "2 weeks ago"
from SYS.DUAL;
--Б) имя пользователя первый равиант:
SELECT USER
FROM DUAL;
-- имя пользователя второй варинат:
SELECT username
FROM user_users;
--имя компьютера:
SELECT userenv('terminal')
FROM DUAL ;
--можно было бы получить данные с таблицы пользователя SYS, но у меня нет прав на её просмотр
--select login_name,host_name from sys.dm_exec_sessions
--B)округление и усечение после запятой:
SELECT FLAT, ROUND(FLAT,1)AS"округлено",TRUNC(FLAT,1)AS"усечено"
FROM FLAT;
--округление и усечение до запятой
SELECT FLAT, ROUND(FLAT,-1)AS"округлено",TRUNC(FLAT,-1)AS"усечено"
FROM FLAT;
--Г)все слова выводятся прописными буквами
SELECT BASE,LOWER(BASE)AS"прописные буквы"
FROM BUILDING;
--все слова выводятся строчными буквами
SELECT BASE,UPPER(BASE)AS"строчные буквы"
FROM BUILDING;
--каждое слово начинается с заглавной
SELECT BASE, INITCAP(BASE)AS"изменения"
FROM BUILDING;
--Д)максмимальная, минимальная и средняя длина строки
--для этого изменим тип данных в поле MATERIAL с фиксированой длины на переменную: VARCHAR2
--максимальная
SELECT DISTINCT LENGTH(MATERIAL) AS "максимальная"
FROM BUILDING
WHERE LENGTH(MATERIAL)>= ALL(SELECT LENGTH(MATERIAL)FROM BUILDING);
--минимальная
SELECT DISTINCT LENGTH(MATERIAL) AS "минимальная"
FROM BUILDING
WHERE LENGTH(MATERIAL)<= ALL(SELECT LENGTH(MATERIAL)FROM BUILDING);
--мин ср и макс
SELECT MIN(LENGTH(MATERIAL))AS"Минимальная",AVG(LENGTH(MATERIAL))AS"средняяя",MAX(LENGTH(MATERIAL))AS"максимальная"
FROM BUILDING;
--E)разделение строк
--предвариательно вернуть таблицу в нормальное состояние
--использовать регулярные выражения для разделения
SELECT regexp_substr(ADDRESS, '[^,]+', 1, 1) улица,
regexp_substr(ADDRESS, '[^,]+', 1, 2) дом
FROM BUILDING;
--Ж)нет таблицы, с типом данных: DATE
--З)уменьшить дату на 3 месяца, увиеличить дату на 2 месяца, количество месяцев между ними
SELECT s1 AS "3 месяца назад" ,s2 AS "2 месяца вперёд",MONTHS_BETWEEN(s2,s1) AS "разница"
from (
SELECT ADD_MONTHS(SYSDATE,-3) AS s1,ADD_MONTHS(SYSDATE,2) AS s2
FROM SYS.DUAL
);
--И)кол-во дней в месяце для примера З:
SELECT regexp_substr(LAST_DAY(s1),'[^-]+',1,1) AS "кол-во дней 2 месяца назад" ,regexp_substr(LAST_DAY(s2),'[^-]+',1,1) AS "2 месяца вперёд"
from (
SELECT ADD_MONTHS(SYSDATE,-3) AS s1,ADD_MONTHS(SYSDATE,2) AS s2
FROM SYS.DUAL
);
--К)вывести дату по коду
--теоретический материал не нашел, в oracle не получилось использовать коды, в msSQL работет(проверял CONVERT, читал про cast но его проверял только в ORACLE)
--сдесь использовал просто приведение типа по формату
SELECT TO_CHAR(d,'YYYY/DD/MM')AS"разделитель слеш", TO_CHAR(d,'dd-MM-YY')AS"разделитель тире", TO_CHAR(d,'YYYY.dd.MM')AS"разделитель точка"
FROM
(
SELECT SYSDATE as d
FROM SYS.DUAL
);
--Л)использовать TO_DATE для вывода даты в разных форматах
--формат вывода не меняется, так как TO_DATE - это функция приведения типов, и по сути мы пытаемся привести формат времени к формату времени
SELECT TO_DATE(d,'dd.MM.YY')
FROM
(
SELECT SYSDATE as d
FROM SYS.DUAL
);
--М)использовать DECODE
SELECT MATERIAL,DECODE(MATERIAL,'Кирпич','К','Железобетон','Ж','Дерево','Д','Без знака')AS"Знак"
FROM BUILDING;
--Н)использовать NVL
SELECT DECORATION, NVL(DECORATION,'Нет отделки')
FROM ROOM;