Читать книгу «Основы программирования в СУБД Oracle. SQL+PL/SQL.» онлайн полностью📖 — О. А. Ткачев — MyBook.
image

Задачи для самостоятельного решения

1. Вывести значения столбцов employee_id, first_name, last_name и значение зарплаты, увеличенное на 25%. Увеличенное значение зарплаты округлить до сотен.

2. Вывести значения столбцов employee_id, first_name, last_name, salary и ту часть зарплаты сотрудника, которая меньше 1000.

3. Создать запрос, который вернет столбец name_and_salaries. Столбец должен содержать полное имя сотрудника, зарплату и несколько звездочек (*) – по одной звездочке на каждые $1000 зарплаты.

4. Вывести данные о товарах, название которых содержит слово AMD и не содержит слова RYZEN.

5. Вывести названия товаров, второе слово которых состоит из шести букв.

6. Вывести данные о товарах, второе слово в названии которых – — iPhone.

7. Вывести данные о сотрудниках, которые были приняты на работу в понедельник.

8. Вывести данные о сотрудниках, которые были приняты на работу 21 апреля.

9. Для сотрудников, работающих в отделе 50, вывести разницу между текущей датой и датой приема на работу в формате: УУ лет ММ месяцев ДД дней.

10. Вывести значения столбцов employee_id, first_name, last_name, salary и премию, которую они должны получить. Размер премии у сотрудников, которые получают комиссионные, равен зарплате с учетом комиссионных. Размер премии у сотрудников, которые не получают комиссионные, равен зарплате, увеличенной на 30%.

11. Вывести значения столбцов employee_id, first_name, last_name, salary и bonus – премию, которую они должны получить. Размер премии зависит от рейтинга и вычисляется по следующему правилу:

– если рейтинг сотрудника равен 5, то bonus = salary * 1.5;

– если рейтинг сотрудника равен 4, то bonus = salary * 1.3;

– если рейтинг сотрудника равен 3, то bonus = salary * 1.1;

– сотрудникам, рейтинг которых меньше 3, премия не полагается.

12. Вывести значения столбцов employee_id, first_name, last_name, salary и category. Значение категории (category) определяется по следующему правилу:

– если rating_e ≥ 4 и salary ≥ 10 000, то category = ′High′;

– если rating_e <3 и salary <5000, то category = ′Low′;

– у остальных сотрудников category = ′Middle′.

Глава 4. Агрегатные функции и группировка данных

Агрегатные функции

В отличие от однострочных функций, агрегатные функции обрабатывают группу строк и возвращают один результат для группы. Группа строк может включать как всю таблицу, так и ее часть.

Таблица 4.1. Агрегатные функции


Синтаксис агрегатных функций:


{имя функции} ({Аргумент})


где: expr – аргумент агрегатной функции, который может содержать следующие элементы:


[DISTINCT] {имя столбца} | {выражение} | {однострочная функция}


Следует обратить внимание на то, что аргументом групповой функции может быть однострочная функция. Хотя стандарт языка SQL запрещает использование агрегатных функций в качестве аргумента агрегатных функций, СУБД Oracle допускает это, но только на один уровень в глубину и только в предложении SELECT. Рассмотрим примеры использования агрегатных функций.


Пример 4.1. Вывод обобщенных данных о зарплате сотрудников


SELECT MIN (salary) AS minimum, MAX (salary) AS maximum, ROUND (AVG (salary)) AS medium, SUM (salary) As summa, COUNT (salary), COUNT (*)

FROM Employees;



В полученном результате следует обратить внимание на то, что:

– COUNT (salary) возвращает число сотрудников, получающих зарплату, у которых значение столбца salary не NULL;

– COUNT (*) возвращает число всех сотрудников.

Этот запрос не учитывает то, что некоторые сотрудники получают комиссионные. Зарплата сотрудника с учетом комиссионных может быть вычислена путем использования выражения:


salary * (1 + NVL (commission_pct,0))


Используя это выражение в предыдущем запросе, вместо столбца salary получим:


Пример 4.2. Вывод обобщенных данных о зарплате сотрудников с учетом комиссионных


SELECT MIN (salary* (1+NVL (commission_pct,0))) AS minimum,

MAX (salary* (1+NVL (commission_pct,0))) AS maximum,

ROUND (AVG (salary* (1+NVL (commission_pct,0)))) AS medium,

SUM (salary* (1+NVL (commission_pct,0))) As summa,

COUNT (salary* (1+NVL (commission_pct,0))) AS ′′COUNT (expr) ′′,

COUNT (*)

FROM Employees;



Пример 4.3. Использование функции COUNT


SELECT COUNT (*), COUNT (salary),COUNT (DISTINCT salary),

COUNT (commission_pct)

FROM Employees

WHERE department_id =80;



Анализ результатов этого запроса:

– COUNT (*) – вернула число сотрудников в отделе 80;


– COUNT (salary) – вернула число сотрудников в отделе 80,

у которых значение столбца salary не NULL;


– COUNT (DISTINCT salary) – вернула число различных значений в столбце salary;


– COUNT (commission_pct) – вернула число сотрудников в отделе 80, у которых значение столбца commission_pct не NULL.


Оператор DISTINCT используется для исключения повторяющихся значений. Например, необходимо определить количество должностей. Запрос без оператора DISTINCT вернет количество сотрудников, у которых значение столбца job_id не NULL.


Пример 4.4. Количество сотрудников, у которых значение столбца job_id не NULL


SELECT COUNT (job_id)

FROM Employees;



Если в аргумент функции COUNT добавить оператор DISTINCT, то будут исключены повторяющиеся значения столбца job_id и запрос вернет количество должностей (количество уникальных значений столбца job_id).


Пример 4.5. Количество уникальных значений столбца job_id


SELECT COUNT (DISTINCT job_id)

FROM Employees;



Задача: требуется определить средний размер комиссионных. Рассмотрим два варианта решения этой задачи.


Вариант 1


SELECT AVG (commission_pct)

FROM Employees;


Вариант 2.


SELECT AVG (NVL (commission_pct, 0))

FROM Employees;


Здесь правильный вариант решения не очевиден. У значительной части сотрудников значение столбца commission_pct имеет значение NULL. Если этим сотрудникам комиссионные не положены и они не должны учитываться, то правильным будет первый вариант. Если значение NULL следует считать равным нулю, то следует использовать второй вариант запроса.

Агрегатные функции нельзя использовать в предложении WHERE. Например, нельзя найти сотрудника с максимальной зарплатой, используя следующий запрос:

Пример 4.6a. Найти сотрудника, получающего максимальную зарплату

Внимание: ЭТОТ ЗАПРОС НЕ БУДЕТ ВЫПОЛНЕН!


SELECT employee_id, salary

FROM Employees

WHERE salary = MAX (salary);


Данную задачу можно решить следующим образом:


Пример 4.6б. Найти сотрудника, получающего максимальную зарплату


SELECT employee_id, salary AS maximum

FROM Employees

WHERE salary = (SELECT MAX (salary) FROM Employees);



Данный запрос содержит в предложении WHERE подзапрос. Использование подзапросов будет рассмотрено позже.