1169 lines
55 KiB
Typst
1169 lines
55 KiB
Typst
#show link: underline
|
||
#set page(
|
||
header: context {
|
||
if counter(page).get().first() == 1 [
|
||
#align(center)[
|
||
Санкт-Петербургский национальный исследовательский университет информационных технологий, механики и оптики
|
||
]
|
||
]
|
||
},
|
||
footer: context {
|
||
if counter(page).get().first() == 1 [
|
||
#align(center)[Санкт-Петербург \ 2025]
|
||
] else [
|
||
#align(center)[#counter(page).display("1")]
|
||
]
|
||
}
|
||
)
|
||
|
||
|
||
#show raw.where(block: false): box.with(
|
||
fill: luma(240),
|
||
inset: (x: 3pt, y: 0pt),
|
||
outset: (y: 3pt),
|
||
radius: 2pt,
|
||
)
|
||
|
||
#show raw.where(block: true): block.with(
|
||
fill: luma(240),
|
||
inset: 10pt,
|
||
radius: 4pt,
|
||
)
|
||
|
||
// title
|
||
|
||
\
|
||
\
|
||
\
|
||
#align(center)[Факультет инфокоммуникационных технологий]
|
||
#align(center)[Направление подготовки 11.03.02]
|
||
\
|
||
\
|
||
#align(center)[Практическая работа №2]
|
||
//#align(center)[Установка и первоначальная настройка субд postgresql.]
|
||
\
|
||
\
|
||
\
|
||
\ //#align(center)[Вариант 19]
|
||
\
|
||
\
|
||
\
|
||
\
|
||
\
|
||
\
|
||
\
|
||
#align(right)[Выполнил:]
|
||
#align(right)[Дощенников Никита Андреевич]
|
||
#align(right)[Группа: К3221]
|
||
#align(right)[Проверила:]
|
||
#align(right)[Татьяна Евгеньевна Войтюк]
|
||
\
|
||
\
|
||
|
||
#pagebreak()
|
||
|
||
=== Цель работы
|
||
|
||
Изучение и освоение SQL для работы с реляционными базами данных, включая:
|
||
|
||
- Формирование запросов на выборку данных с оператором `SELECT`
|
||
|
||
- Применение `WHERE` и `ORDER BY` для фильтрации и сортировки данных
|
||
|
||
- Использование функций SQL для обработки данных
|
||
|
||
- Работу с условными выражениями для формирования вычисляемых полей
|
||
|
||
- Получение навыков создания запросов с применением операторов и функций
|
||
|
||
|
||
=== Задачи, решаемые при выполнении работы
|
||
|
||
- Изучить операции с таблицами.
|
||
- Научиться фильтровать и ограничивать данные.
|
||
- Освоить работу с числовыми функциями.
|
||
- Изучить символьные функции.
|
||
- Освоить функции работы с датами.
|
||
- Научиться использовать условные выражения.
|
||
- Развить навыки анализа и отладки SQL-запросов.
|
||
|
||
=== Исходные данные
|
||
|
||
Для выполнения используется база данных `EmployeesDepartments`.
|
||
|
||
1. Таблица `EMPLOYEES`
|
||
|
||
Содержит информацию о сотрудниках компании с полями:
|
||
- `EMPLOYEE_ID` – идентификационный номер сотрудника (числовой)
|
||
- `FIRST_NAME` – имя сотрудника (строковый)
|
||
- `LAST_NAME` – фамилия сотрудника (строковый)
|
||
- `EMAIL` – электронная почта (строковый)
|
||
- `PHONE_NUMBER` – номер телефона (строковый)
|
||
- `HIRE_DATE` – дата найма (дата)
|
||
- `JOB_ID` – идентификатор должности (строковый)
|
||
- `SALARY` – оклад сотрудника (числовой)
|
||
- `COMMISSION_PCT` – процент комиссионных (числовой)
|
||
- `MANAGER_ID` – идентификатор менеджера (числовой)
|
||
- `DEPARTMENT_ID` – идентификатор отдела (числовой)
|
||
|
||
2. Таблица DEPARTMENTS
|
||
|
||
Содержит информацию об отделах компании с полями:
|
||
- `DEPARTMENT_ID` – идентификационный номер отдела (числовой)
|
||
- `DEPARTMENT_NAME` – название отдела (строковый)
|
||
- `MANAGER_ID` – идентификатор руководителя отдела (числовой)
|
||
- `LOCATION_ID` – идентификатор местоположения (числовой)
|
||
|
||
3. Таблица JOB_GRADES
|
||
|
||
Содержит информацию о разрядах различных должностей.
|
||
|
||
=== Выполнение работы
|
||
|
||
==== Задание 1. Описание структуры таблицы, выборка данных из таблицы, задание имен столбцов, сортировка строк с помощью предложения ORDER BY
|
||
|
||
===== 1.1 Будет ли успешна эта команда `SELECT`?
|
||
|
||
```sql
|
||
SELECT *
|
||
FROM "EmployeesDepartments".JOB_GRADES;
|
||
```
|
||
|
||
Нет, не будет, так как для корректного выполнения данной команды, нужно добавить кавычки у `JOB_GRADES` (Рис. 1).
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/1.png"),
|
||
supplement: [Рис.],
|
||
caption: [Исполнение исправленного запроса.]
|
||
)
|
||
]
|
||
|
||
===== 1.2 Команда SELECT содержит 4 ошибки. Укажите их.
|
||
|
||
```sql
|
||
SELECT "EMPLOYEE_ID", "LAST_NAME"
|
||
"SAL" x 12 ANNUAL SALARY
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
```
|
||
|
||
- Нет запятой перед `"SAL"`.
|
||
- Использовать `*` вместо `x`.
|
||
- Нужен `AS` и, раз в псевдониме пробел, - кавычки.
|
||
- Вместо `SAL` должно быть `SALARY`.
|
||
|
||
Исправленная версия (Рис. 2):
|
||
|
||
```sql
|
||
SELECT "EMPLOYEE_ID", "LAST_NAME", "SALARY" * 12 AS "ANNUAL SALARY"
|
||
FROM "EmployeesDepartments"."EMPLOYEES";
|
||
```
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/4.png"),
|
||
supplement: [Рис.],
|
||
caption: [Исполнение исправленного запроса.]
|
||
)
|
||
]
|
||
|
||
===== 1.3 Напишите запрос, который отображает структуру таблицы `DEPARTMENTS`, представленную на таблице 1. Сформируйте запрос на выборку данных из нее, результат должен соответствовать таблице 2.
|
||
|
||
// таблица 1
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 3)[*column_name*][*is_nullable*][*Type*][DEPARTMENT_ID][NO][smallint][DEPARTMENT_NAME][NO][character varying][MANAGER_ID][YES][integer][LOCATION_ID][YES][smallint],
|
||
caption: [Структура таблицы `DEPARTMENTS`.],
|
||
supplement: [Табл.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT column_name,
|
||
CASE WHEN is_nullable = 'YES' THEN 'YES' ELSE 'NO' END AS is_nullable,
|
||
data_type
|
||
FROM information_schema.columns
|
||
WHERE table_name = 'DEPARTMENTS'
|
||
AND table_schema IN ('EmployeesDepartments', 'public')
|
||
ORDER BY ordinal_position;
|
||
```
|
||
|
||
Извлекает данные таблицы `DEPARTMENTS` из представления `information_schema.columns`.
|
||
- `column_name` — имя столбца;
|
||
- `is_nullable` — может ли столбец содержать null;
|
||
- `data_type` — тип данных столбца.
|
||
|
||
Фильтрация по `table_name` и `table_schema` позволяет получить только нужную таблицу. Сортировка по `ordinal_position` отображает столбцы в порядке их создания в таблице. Результат выполнения скрипта представлен на рисунке 3.
|
||
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/2.png"),
|
||
caption: [Результат выполнения запроса.],
|
||
supplement: [Рис.]
|
||
)
|
||
]
|
||
|
||
// таблица 2
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 4)[*DEPARTMENT_ID*][*DEPARTMENT_NAME*][*MANAGER_ID*][*LOCATION_ID*][10][Administration][200][1700][20][Marketing][201][1800][50][Shipping][124][1500][60][IT][103][1400][80][Sales - Europe][149][2500][85][Sales - Americas][149][2100][90][Executive][100][1700][110][Accounting][205][1700][190][Contracting][][1700],
|
||
caption: [Результат выполнения запроса к таблице `DEPARTMENTS`.],
|
||
supplement: [Табл.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "DEPARTMENT_ID", "DEPARTMENT_NAME", "MANAGER_ID", "LOCATION_ID"
|
||
FROM "EmployeesDepartments"."DEPARTMENTS"
|
||
ORDER BY "DEPARTMENT_ID";
|
||
```
|
||
|
||
Этот запрос выбирает все данные из таблицы `DEPARTMENTS` в схеме `EmployeesDepartments`. Сортировка по `DEPARTMENT_ID` обеспечивает упорядоченный вывод строк. Результат выполнения запроса представлен на рисунке 4.
|
||
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/3.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
===== 1.4 Напишите запрос, который отображает структуру таблицы `EMPLOYEES`, представленную в таблице 3.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 3)[*Name*][*Null?*][*Type*][HIRE_DATE][NO][date][SALARY][YES][numeric][COMMISION_PCT][YES][numeric][MANAGER_ID][YES][integer][DEPARTMENT_ID][YES][smallint][EMPLOYEE_ID][NO][integer][BONUS][YES][character varying][FIRST_NAME][YES][character varying][LAST_NAME][NO][character varying][EMAIL][NO][character varying][PHONE_NUMBER][YES][character varying][JOB_ID][NO][character varying],
|
||
caption: [Результат выполнения запроса к таблице `DEPARTMENTS`.],
|
||
supplement: [Табл.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT column_name AS "Name",
|
||
CASE WHEN is_nullable = 'YES' THEN 'YES' ELSE 'NO' END AS "Null?",
|
||
data_type AS "Type"
|
||
FROM information_schema.columns
|
||
WHERE table_schema = 'EmployeesDepartments'
|
||
AND table_name = 'EMPLOYEES'
|
||
ORDER BY ordinal_position;
|
||
```
|
||
|
||
Этот запрос извлекает информацию о столбцах таблицы `EMPLOYEES`:
|
||
- `Name` — имя столбца;
|
||
- `Null?` — может ли столбец содержать null;
|
||
- `Type` — тип данных столбца.
|
||
|
||
Фильтрация по `table_schema` и `table_name` позволяет получить данные только для нужной таблицы. Сортировка по `ordinal_position` отображает столбцы в том порядке, в котором они были созданы в таблице. Результат запроса приведен на рисунке 5.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/5.png"),
|
||
caption: [Результат выполнения запроса.],
|
||
supplement: [Рис.]
|
||
)
|
||
]
|
||
|
||
|
||
|
||
===== 1.5 Составьте запрос для вывода фамилии каждого служащего, должности, даты найма и номера. Номер служащего должен быть первым. Результат запроса должен быть схож с таблицей 4.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 4)[*EMPLOYEE_ID*][*LAST_NAME*][*JOB_ID*][*HIRE_DATE*][100][King][AD_PRES][2002-06-17][101][Kochhar][AD_VP][2004-09-21][102][De Haan][AD_VP][2008-01-13][103][Hunold][IT_PROG][2005-01-03][104][Ernst][IT_PROG][2006-05-21][107][Lorentz][IT_PROG][2014-02-07][124][Mourgos][ST_MAN][2014-11-16][141][Rajs][ST_CLERK][2010-10-17][142][Davies][ST_CLERK][2012-01-29][143][Matos][ST_CLERK][2013-03-15][144][Vargas][ST_CLERK][2013-07-09][$dots$][$dots$][$dots$][$dots$],
|
||
caption: [Часть результата выполнения запроса из пункта 1.5.],
|
||
supplement: [Табл.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "EMPLOYEE_ID",
|
||
"LAST_NAME",
|
||
"JOB_ID",
|
||
"HIRE_DATE"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
ORDER BY "EMPLOYEE_ID";
|
||
```
|
||
|
||
В этом запросе выбираются четыре столбца таблицы `EMPLOYEES`:
|
||
- `EMPLOYEE_ID` — идентификатор сотрудника, выводится первым;
|
||
- `LAST_NAME` — фамилия сотрудника;
|
||
- `JOB_ID` — код должности;
|
||
- `HIRE_DATE` — дата найма.
|
||
|
||
Сортировка по `EMPLOYEE_ID` обеспечивает упорядоченный вывод. Результат выполнения запроса представлен на рисунке 6.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/6.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
===== 1.6 Составьте запрос для вывода неповторяющихся должностей из таблицы EMPLOYEES, результат должен соответствовать таблице 5.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 1)[*JOB_ID*][AC_ACCOUNT][AC_MGR][AD_ASST][AD_PRES][AD_VP][IT_PROG][MK_MAN][MK_REP][SA_MAN][SA_REP][SR_MK_REP][SR_SA_REP][SR_ST_CLRK][ST_CLERK][ST_MAN],
|
||
caption: [Результат выполнения запроса для вывода неповторяющихся должностей.],
|
||
supplement: [Табл.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT DISTINCT "JOB_ID"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
ORDER BY "JOB_ID";
|
||
```
|
||
|
||
В этом запросе используется ключевое слово `DISTINCT` для того, чтобы выбрать только уникальные значения столбца `JOB_ID` из таблицы `EMPLOYEES`. Сортировка по `JOB_ID` упорядочивает результат по алфавиту. Результат выполнения запроса представлен на рисунке 7.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/7.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
|
||
===== 1.7 Выведите на экран фамилию, соединенную с идентификатором должности через запятую и пробел. Назовите новый столбец Employee and Title. Результат запроса должен быть схож с таблицей 6.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 1)[*Employee and Title*][King, AD_PRES][Kochhar, AD_VP][De Haan, AD_VP][Hunold, IT_PROG][Ernst, IT_PROG][Lorentz, IT_PROG][Mourgos, ST_MAN][Rajs, ST_CLERK][Davies, ST_CLERK][Matos, ST_CLERK][Vargas, ST_CLERK][$dots$],
|
||
caption: [Результат выполнения запроса для вывода фамилии, соединённой с идентификатором должности.],
|
||
supplement: [Табл.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "LAST_NAME" || ', ' || "JOB_ID" AS "Employee and Title"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
ORDER BY "EMPLOYEE_ID";
|
||
```
|
||
|
||
В этом запросе используется оператор `||` для конкатенации строк:
|
||
- сначала `LAST_NAME`,
|
||
- затем запятая и пробел `', '`,
|
||
- затем `JOB_ID`.
|
||
|
||
Результат выводится под новым именем столбца `Employee and Title`. Результат выполнения запроса представлен на рисунке 8.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/8.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
|
||
==== Задание 2. Выборка данных и изменение последовательности вывода строк, ограничение количества возвращаемых строк с помощью предложения `WHERE`, сортировка строк с помощью предложения `ORDER BY`.
|
||
|
||
===== 2.1 Создайте запрос для вывода фамилии и заработной платы служащих, зарабатывающих более 12000. Результат выполнения запроса должен соответствовать таблице 7.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 2)[*LAST_NAME*][*SALARY*][King][24000][Kochhar][17000][De Haan][17000][Hartstein][13000],
|
||
caption: [Результат выполнения запроса для вывода фамилии и заработной платы служащих],
|
||
supplement: [Рис.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "LAST_NAME", "SALARY"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
WHERE "SALARY" > 12000
|
||
ORDER BY "SALARY" DESC;
|
||
```
|
||
|
||
- выбираются столбцы `LAST_NAME` и `SALARY` из таблицы `EMPLOYEES`;
|
||
- фильтруются только те строки, где заработная плата больше 12000;
|
||
- строки сортируются по убыванию зарплаты, чтобы сначала отображались сотрудники с наибольшей зарплатой.
|
||
|
||
Результат выполнения запроса представлен на рисунке 9.
|
||
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/9.png"),
|
||
caption: [Результат выполнения запроса.],
|
||
supplement: [Рис.]
|
||
)
|
||
]
|
||
|
||
===== 2.2 Создайте запрос для вывода фамилии и номера отдела служащего под номером 176. Результат выполнения запроса должен соответствовать таблице 7.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 2)[*LAST_NAME*][*DEPARTMENT_ID*][Taylor][80],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса для служащего под номером 176.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "LAST_NAME", "DEPARTMENT_ID"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
WHERE "EMPLOYEE_ID" = 176;
|
||
```
|
||
|
||
- выбираются столбцы `LAST_NAME` и `DEPARTMENT_ID` из таблицы `EMPLOYEES`;
|
||
- фильтрация выполняется по точному значению `EMPLOYEE_ID` с помощью условия `WHERE`;
|
||
|
||
Результат выполнения запроса представлен на рисунке 10.
|
||
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/10.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
===== 2.3 Измените запрос из задания 2.1 и выведите фамилии и оклады всех служащих, чей оклад не входит в диапазон от 5000 до 12000. Результат выполнения запроса должен быть схож с таблицей 8.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 2)[*LAST_NAME*][*SALARY*][King][24000.00][Kochhar][17000.00][De Haan][17000.00][Lorentz][4200.00][Rajs][3500.00][Davies][3100.00][Matos][2600.00][Vargas][2500.00][Whalen][4400.00][Hartstein][13000.00],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса для служащих, чей оклад не входит в диапазон от 5000 до 12000.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "LAST_NAME", "SALARY"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
WHERE "SALARY" < 5000 OR "SALARY" > 12000
|
||
ORDER BY "SALARY" DESC;
|
||
```
|
||
|
||
- выбираются столбцы `LAST_NAME` и `SALARY` из таблицы `EMPLOYEES`;
|
||
- фильтруются строки, где оклад не входит в диапазон от 5000 до 12000, с помощью условия `WHERE ... OR`;
|
||
- строки сортируются по убыванию оклада.
|
||
|
||
Результат выполнения запроса представлен на рисунке 11.
|
||
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/11.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
===== 2.4 Выведите фамилию, идентификатор должности и дату начала работы всех служащих, нанятых в период с 16 февраля 2011 по 12 мая 2011г. Отсортируйте данные в порядке возрастания даты найма. Результат выполнения запроса должен соответствовать таблице 9.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 3)[*LAST_NAME*][*JOB_ID*][*HIRE_DATE*][Hartstein][MK_MAN][2011-02-17][Abel][SA_REP][2011-05-11],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса для служащих, нанятых в период с 16 февраля 2011 по 12 мая 2011г.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "LAST_NAME", "JOB_ID", "HIRE_DATE"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
WHERE "HIRE_DATE" BETWEEN '2011-02-16' AND '2011-05-12'
|
||
ORDER BY "HIRE_DATE" ASC;
|
||
```
|
||
|
||
- выбираются столбцы `LAST_NAME`, `JOB_ID` и `HIRE_DATE` из таблицы `EMPLOYEES`;
|
||
- фильтрация выполняется по дате найма с помощью предложения `WHERE` и `BETWEEN`, чтобы выбрать сотрудников, нанятых с 16 февраля по 12 мая 2011 года включительно;
|
||
- сортировка по возрастанию даты найма.
|
||
|
||
Результат выполнения запроса представлен на рисунке 12.
|
||
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/12.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
===== 2.5 Выведите фамилию и номер отдела всех служащих из отделов 20 и 50. Отсортируйте данные по фамилиям в алфавитном порядке. Результат выполнения запроса должен быть схож с таблицей 10.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 2)[*LAST_NAME*][*DEPARTMENT_ID*][Bell][50][Davies][50][Fay][20][Hartstein][20][Heiden][50][Matos][50][Mourgos][50],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса для служащих из отделов 20 и 50.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "LAST_NAME", "DEPARTMENT_ID"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
WHERE "DEPARTMENT_ID" IN (20, 50)
|
||
ORDER BY "LAST_NAME" ASC;
|
||
```
|
||
|
||
- выбираются столбцы `LAST_NAME` и `DEPARTMENT_ID` из таблицы `EMPLOYEES`;
|
||
- фильтруются сотрудники, работающие в отделах 20 и 50 с помощью условия `WHERE ... IN`;
|
||
- сортировка по фамилии.
|
||
|
||
Результат выполнения запроса представлен на рисунке 13.
|
||
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/13.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
===== 2.6 Измените запрос из задания 2.3 для вывода фамилий и окладов служащих отделов 20 и 50, зарабатывающих от 5000 до 12000. Назовите столбцы Employee и Mounthly Salary, соответственно. Результат выполнения запроса должен соответствовать таблице 11.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 2)[*EMPLOYEE*][*Mounthly Salary*][Safwah][5000.00][Mourgos][5800.00][Steiner][8600.00],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса для служащих из отделов 20 и 50, зарабатывающих от 5000 до 12000.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "LAST_NAME" AS "EMPLOYEE", "SALARY" AS "Mounthly Salary"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
WHERE "DEPARTMENT_ID" IN (20, 50)
|
||
AND "SALARY" BETWEEN 5000 AND 12000
|
||
ORDER BY "LAST_NAME" ASC;
|
||
```
|
||
|
||
- выбираются столбцы `LAST_NAME` и `SALARY` из таблицы `EMPLOYEES`;
|
||
- столбцы переименовываются через `AS` в `EMPLOYEE` и `Mounthly Salary`;
|
||
- фильтруются сотрудники, работающие в отделах 20 и 50 с зарплатой от 5000 до 12000 с помощью `WHERE ... AND ... BETWEEN`;
|
||
- сортировка по фамилии.
|
||
|
||
Результат выполнения запроса представлен на рисунке 14.
|
||
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/14.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
|
||
===== 2.7 Выведите фамилии и должности всех служащих, не имеющих менеджера. Результат выполнения запроса должен соответствовать таблице 12.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 2)[*LAST_NAME*][*JOB_ID*][King][AD_PRES],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса для служащих, не имеющих менеджера.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "LAST_NAME", "JOB_ID"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
WHERE "MANAGER_ID" IS NULL;
|
||
```
|
||
|
||
- выбираются столбцы `LAST_NAME` и `JOB_ID` из таблицы `EMPLOYEES`;
|
||
- фильтруются сотрудники, у которых нет менеджера, с помощью условия `WHERE "MANAGER_ID" IS NULL`;
|
||
- результат содержит только тех сотрудников, которые не подчиняются никому.
|
||
|
||
Результат выполнения запроса представлен на рисунке 15.
|
||
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/15.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
|
||
===== 2.8 Выведите фамилию, и комиссионные всех служащих, зарабатывающих комиссионные. Отсортируйте данные в порядке убывания окладов и комиссионных. Результат выполнения запроса должен соответствовать таблице 13.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 3)[*LAST_NAME*][*SALARY*][*COMMISION_PCT*][Grant][7000.00][0.15][Alves Rocha][7300.00][0.15][Almeida Castro][7300.00][0.20][Silva Pinto][7500.00][0.15][Taylor][8600.00][0.20][Barbosa Souza][9500.00][0.20][Hooper][9600.00][0.20][Zlotkey][10500.00][0.20][Abel][11000.00][0.30],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса для служащих, зарабатывающих комиссионные.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "LAST_NAME", "SALARY", "COMMISSION_PCT"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
WHERE "COMMISSION_PCT" IS NOT NULL
|
||
ORDER BY "SALARY" DESC, "COMMISSION_PCT" DESC;
|
||
```
|
||
|
||
- `WHERE "COMMISSION_PCT" IS NOT NULL` — отбирает только сотрудников, которые получают комиссионные.
|
||
- `ORDER BY "SALARY" DESC, "COMMISSION_PCT" DESC` — сортировка по зарплате сначала от большей к меньшей, а при равной зарплате — по комиссионным.
|
||
|
||
Результат выполнения запроса представлен на рисунке 16.
|
||
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/16.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
|
||
===== 2.9 Выведите все фамилии служащих БЕЗ использования строковых функций, в которых третья буква - _а_. Результат выполнения запроса должен соответствовать таблице 14.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 1)[*LAST_NAME*][Grant][Whalen],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса (фамилии служащих, в которых третья буква _a_).]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "LAST_NAME"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
WHERE "LAST_NAME" LIKE '__a%'
|
||
ORDER BY "LAST_NAME" ASC;
|
||
```
|
||
|
||
- используется оператор `LIKE` для поиска шаблона в столбце `LAST_NAME`;
|
||
- `'__a%'` означает:
|
||
- первые две символа могут быть любыми,
|
||
- третий символ — буква 'a',
|
||
- `%` соответствует любому количеству оставшихся символов;
|
||
- сортировка по фамилии.
|
||
|
||
Результат выполнения запроса представлен на рисунке 17.
|
||
|
||
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/17.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
|
||
===== 2.10 Выведите фамилии, должности и оклады всех служащих, работающих торговыми представителями (SA_REP) или клерками на складе (ST_CLERK), с окладом не равным 2600, 3100, 8600 и 11000. Результат выполнения запроса должен соответствовать таблице 15.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 3)[*LAST_NAME*][*JOB_ID*][*SALARY*][Rajs][ST_CLERK][3500.00][Vargas][ST_CLERK][2500.00][Grant][SA_REP][7000.0][Silva Pinto][SA_REP][7500.00][Alves Rocha][SA_REP][7300.00][Almeida Castro][SA_REP][7300.00],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "LAST_NAME", "JOB_ID", "SALARY"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
WHERE "JOB_ID" IN ('SA_REP', 'ST_CLERK')
|
||
AND "SALARY" NOT IN (2600, 3100, 8600, 11000)
|
||
ORDER BY "LAST_NAME" ASC;
|
||
```
|
||
|
||
- выбираются столбцы `LAST_NAME`, `JOB_ID` и `SALARY` из таблицы `EMPLOYEES`;
|
||
- фильтруются только сотрудники с должностями `SA_REP` или `ST_CLERK` c помощью условия `WHERE ... IN`;
|
||
- дополнительно исключаются строки с окладами 2600, 3100, 8600 и 11000 с помощью `NOT IN`;
|
||
- сортировка по фамилии.
|
||
|
||
|
||
Результат выполнения запроса представлен на рисунке 18.
|
||
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/18.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
|
||
===== 2.11 Измените запрос 2.8 так, чтобы получить фамилии, оклады и комиссионные всех служащих, у которых сумма комиссионных равна или превышает 20%. Выполните запрос еще раз. Результат выполнения запроса должен соответствовать таблице 16.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 3)[*Employee*][*Monthly Salary*][*COMMISION_PCT*][Almeida Castro][7300.00][0.20][Taylor][8600.00][0.20][Barbosa Souza][9500.00][0.20][Hooper][9600.00][0.20][Zlotkey][10500.00][0.20][Abel][11000.00][0.30],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "LAST_NAME" AS "Employee",
|
||
"SALARY" AS "Monthly Salary",
|
||
"COMMISSION_PCT"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
WHERE "COMMISSION_PCT" >= 0.20
|
||
ORDER BY "LAST_NAME" ASC;
|
||
```
|
||
|
||
- выбираются фамилии сотрудников `LAST_NAME`, месячная зарплата `SALARY` и процент комиссионных `COMMISSION_PCT`;
|
||
- фильтруются только те сотрудники, у которых `COMMISSION_PCT` $gt.eq$ 0.20, то есть сумма комиссионных равна или превышает 20%;
|
||
- столбцы переименованы с помощью `AS`;
|
||
- сортировка по фамилии.
|
||
|
||
Результат выполнения запроса представлен на рисунке 19.
|
||
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/19.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
==== Задание 3. Составление запросов, требующих использования числовых функций (TRUNC, ROUND и т.д.)
|
||
|
||
===== 3.1 Выведите номер служащего, его фамилию, оклад, повышенный на 9.5%. Новый оклад должен быть округлен до целого. Назовите столбец New Salary. Результат выполнения запроса должен быть подобен результату, представленному в таблице 17.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 4)[*EMPLOYEE_ID*][*LAST_NAME*][*SALARY*][*New Salary*][100][King][24000.00][26280][101][Kochhar][17000.00][18615][102][De Haan][17000.00][18615][103][Hunold][9000.00][9855][104][Ernst][6000.00][6570][$dots$][$dots$][$dots$][$dots$],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "EMPLOYEE_ID",
|
||
"LAST_NAME",
|
||
"SALARY",
|
||
ROUND("SALARY" * 1.095) AS "New Salary"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
ORDER BY "EMPLOYEE_ID";
|
||
```
|
||
|
||
- выбираются столбцы `EMPLOYEE_ID`, `LAST_NAME` и `SALARY` из таблицы `EMPLOYEES`;
|
||
- новый столбец `New Salary` рассчитывается как оклад, увеличенный на 9.5%: `SALARY` $dot$ 1.095;
|
||
- функция `ROUND` округляет полученное значение до целого числа;
|
||
- с помощью `ORDER BY "EMPLOYEE_ID"` строки сортируются по номеру сотрудника.
|
||
|
||
Результат выполнения запроса представлен на рисунке 20.
|
||
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/20.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
===== 3.2 Измените запрос из пункта 3.1, добавив еще один столбец, который будет содержать результат вычитания старого оклада из нового. Назовите столбец Increase. Результат выполнения запроса должен быть подобен результату, представленному в таблице 18.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 5)[*EMPLOYEE_ID*][*LAST_NAME*][*SALARY*][*New Salary*][*Increase*][100][King][24000.00][26280][2280][101][Kochhar][17000.00][18615][1615][102][De Haan][17000.00][18615][1615][103][Hunold][9000.00][9855][855][104][Ernst][6000.00][6570][570][$dots$][$dots$][$dots$][$dots$][$dots$],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "EMPLOYEE_ID",
|
||
"LAST_NAME",
|
||
"SALARY",
|
||
ROUND("SALARY" * 1.095) AS "New Salary",
|
||
ROUND("SALARY" * 1.095) - "SALARY" AS "Increase"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
ORDER BY "EMPLOYEE_ID";
|
||
```
|
||
|
||
- используется выражение из задания 3.1 для расчёта нового оклада, округлённого функцией `ROUND`;
|
||
- добавлен новый столбец `Increase`, который вычисляется как разница между новым и старым окладом;
|
||
- это позволяет увидеть, насколько увеличилась зарплата каждого сотрудника после повышения на 9.5%;
|
||
- строки сортируются по идентификатору сотрудника.
|
||
|
||
|
||
Результат выполнения запроса представлен на рисунке 21.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/21.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
==== Задание 4. Составление запросов, требующих символьных функций (INITCAP, POSITION, LENGTH, CONCAT и т.д.)
|
||
|
||
===== 4.1 Создайте запрос для вывода всех данных из таблицы EMPLOYEES. Разделите столбцы запятыми. Назовите столбец THE_OUTPUT. Результат запроса должен быть схож с таблицей 19.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 1)[*THE_OUTPUT*][100, Steven, King, SKING, 515.123.4567, 2002-06-17, AD_PRES, 24000.00, , , 90][101, Neena, Kochhar, NKOCHHAR, 515.123.4568, 2004-09-21, AD_VP, 17000.00, , 100, 90][102, Lex, De Haan, LDEHAAN, 515.123.4569, 2008-01-13, AD_VP, 17000.00, , 100, 90][103, Alexander, Hunold, AHUNOLD, 590.423.4567, 2005-01-03, IT_PROG, 9000.00, , 102, 60][104, Bruce, Ernst, BERNST, 590.423.4568, 2006-05-21, IT_PROG, 6000.00, , 103, 60][107, Diana, Lorentz, DLORENTZ, 590.423.5567, 2014-02-07, IT_PROG, 4200.00, , 103, 60][$dots$],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT
|
||
CONCAT(
|
||
"EMPLOYEE_ID", ', ',
|
||
"FIRST_NAME", ', ',
|
||
"LAST_NAME", ', ',
|
||
"EMAIL", ', ',
|
||
"PHONE_NUMBER", ', ',
|
||
"HIRE_DATE", ', ',
|
||
"JOB_ID", ', ',
|
||
"SALARY", ', ',
|
||
"COMMISSION_PCT", ', ',
|
||
"MANAGER_ID", ', ',
|
||
"DEPARTMENT_ID"
|
||
) AS "THE_OUTPUT"
|
||
FROM "EmployeesDepartments"."EMPLOYEES";
|
||
```
|
||
|
||
- каждое значение соединяется через запятую и пробел ', ';
|
||
- функция `CONCAT` объединяет текстовые фрагменты;
|
||
- все данные из таблицы выводятся в один столбец `THE_OUTPUT`.
|
||
|
||
Результат выполнения запроса представлен на рисунке 22.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/22.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
===== 4.2 Создайте запрос для вывода фамилий служащих (первая буква каждой фамилии должна быть заглавной, а остальные - строчными) и длину каждой фамилии для тех служащих, фамилия которых начинается с символа _J, A_ или _M_. Присвойте соответствующие заголовки столбцам. Результат выполнения запроса должен соответствовать таблице 20.
|
||
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 2)[*Name*][*Length*]["Abel"][4]["Almeida Castro"][14]["Alves Rocha"][11]["Matos"][5]["Mourgos"][7],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT
|
||
INITCAP("LAST_NAME") AS "Name",
|
||
LENGTH("LAST_NAME") AS "Length"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
WHERE UPPER(SUBSTR("LAST_NAME", 1, 1)) IN ('J', 'A', 'M');
|
||
```
|
||
|
||
- `INITCAP("LAST_NAME")` делает первую букву фамилии заглавной, а остальные строчными;
|
||
- `LENGTH("LAST_NAME")` вычисляет количество символов в фамилии;
|
||
- `SUBSTR("LAST_NAME", 1, 1)` извлекает первый символ фамилии;
|
||
- `UPPER(...) IN ('J','A','M')` отбирает только тех сотрудников, чья фамилия начинается на _J_, _A_ или _M_ (без учёта регистра);
|
||
- Результат выводится в два столбца:
|
||
- `Name` — фамилия с правильным регистром,
|
||
- `Length` — длина фамилии.
|
||
|
||
Результат выполнения запроса представлен на рисунке 23.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/23.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
|
||
|
||
===== 4.3 Создайте запрос для вывода информации по каждому служащему в следующем виде: \<фамилия\> зарабатывает \<оклад\> в месяц, но желает \<утроенный оклад\>. Назовите столбец Dream Salaries. Результат запроса должен быть схож с таблицей 21.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 1)[*Dream Salaries*][King зарабатывает 24000 в месяц, но желает 72000][Kochhar зарабатывает 17000 в месяц, но желает 51000][De Haan зарабатывает 17000 в месяц, но желает 51000][Whalen зарабатывает 4400 в месяц, но желает 13200][Higgins зарабатывает 12000 в месяц, но желает 36000][$dots$],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT
|
||
CONCAT(
|
||
"LAST_NAME",
|
||
' зарабатывает ',
|
||
"SALARY",
|
||
' в месяц, но желает ',
|
||
"SALARY" * 3
|
||
) AS "Dream Salaries"
|
||
FROM "EmployeesDepartments"."EMPLOYEES";
|
||
```
|
||
|
||
- `CONCAT` объединяет несколько частей строки в одно выражение;
|
||
- `LAST_NAME` фамилия сотрудника;
|
||
- `SALARY` его текущий оклад;
|
||
- `"SALARY" * 3` утроенный оклад;
|
||
- все фрагменты объединяются в предложение.
|
||
|
||
Результат выполнения скрипта представлен на рисунке 24.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/24.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
==== Задание 5. Составление запросов, требующих функций для работы с датами и функции преобразования типов.
|
||
|
||
===== 5.1 Напишите запрос для вывода текущей даты. Назовите столбец Date. Результат выполнения запроса должен быть подобен результату, представленному на таблице 22.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 1)[*DATE*][2024-10-20],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса текущей даты.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT CURRENT_DATE AS "Date";
|
||
```
|
||
|
||
- `CURRENT_DATE` стандартная функция, возвращающая текущую системную дату;
|
||
- `AS "Date"` задаёт имя столбца.
|
||
|
||
Резултат выполнения запроса представлен на рисунке 25.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/25.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
===== 5.2 Создайте запрос для вывода фамилии и даты найма всех служащих, нанятых в 2011 г. Результат выполнения запроса должен соответствовать таблице 23.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 2)[*LAST_NAME*][*HIRE_DATE*][Alves Rocha][2011-02-06][Hartstein][2011-02-17][Abel][2011-05-11][Hernandez][2011-06-13],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса для служащих, нанятых в 2011г.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT "LAST_NAME", "HIRE_DATE"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
WHERE EXTRACT(YEAR FROM "HIRE_DATE") = 2011;
|
||
```
|
||
|
||
- `EXTRACT(YEAR FROM "HIRE_DATE")` извлекает год из даты найма;
|
||
- `= 2011` выбирает только тех сотрудников, у которых год найма равен 2011.
|
||
|
||
Результат выполнения запроса представлен на рисунке 26.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/26.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
===== 5.3 Создайте запрос, который позволяет для каждого служащего вывести фамилию, дату найма и вычислят количество месяцев со дня найма до настоящего времени. Назовите столбец MONTH_WORKED. Результаты отсортируйте по количеству отработанных месяцев. Результат выполнения запроса должен быть схож с таблицей 24.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 3)[*LAST_NAME*][*HIRE_DATE*][*MONTH_WORKED*][Safwah][1997-01-06][345][King][2002-06-17][280][Whalen][2002-09-17][277][Kochhar][2004-09-21][252][Steiner][2004-11-02][251][Hunold][2005-01-03][249][Ernst][2006-05-21][232][Reinhard][2007-07-25][218][$dots$][$dots$][$dots$],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT
|
||
"LAST_NAME",
|
||
"HIRE_DATE",
|
||
(EXTRACT(YEAR FROM AGE(CURRENT_DATE, "HIRE_DATE")) * 12
|
||
+ EXTRACT(MONTH FROM AGE(CURRENT_DATE, "HIRE_DATE"))) AS "MONTH_WORKED"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
ORDER BY "MONTH_WORKED" DESC;
|
||
```
|
||
|
||
- `AGE(CURRENT_DATE, "HIRE_DATE")` — возвращает интервал между двумя датами;
|
||
- `EXTRACT(YEAR FROM AGE(...)) * 12 + EXTRACT(MONTH FROM AGE(...))` переводит годы и месяцы в общее количество месяцев;
|
||
- `ORDER BY "MONTH_WORKED" DESC` сортирует по количеству месяцев в порядке убывания.
|
||
|
||
Результат выполнения запроса представлен на рисунке 27.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/27.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
===== 5.4 Создайте запрос, который позволяет для каждого служащего вывести фамилию, дату найма и день недели, когда он был нанят на работу. Назовите последний столбец DAY. Отсортируйте результаты по датам. Результат выполнения запроса должен быть схож с таблицей 25.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 3)[*LAST_NAME*][*HIRE_DATE*][*DAY*][Stocks][2015-12-16][WEDNESDAY][Newton][2015-12-16][WEDNESDAY][Heiden][2015-07-06][MONDAY][Ricci][2015-05-17][SUNDAY][Zlotkey][2015-01-29][THURSDAY][Mourgos][2014-11-16][SUNDAY][Grant][2014-05-24][SATURDAY][Bell][2014-04-01][TUESDAY][Lorentz][2014-02-07][FRIDAY][$dots$][$dots$][$dots$],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT
|
||
"LAST_NAME",
|
||
"HIRE_DATE",
|
||
TO_CHAR("HIRE_DATE", 'FMDay') AS "DAY"
|
||
FROM "EmployeesDepartments"."EMPLOYEES"
|
||
ORDER BY "HIRE_DATE";
|
||
```
|
||
|
||
- `TO_CHAR("HIRE_DATE", 'FMDay')` преобразует дату в название дня недели;
|
||
- `FM` убирает лишние пробелы в начале и конце;
|
||
- возвращается день недели полностью;
|
||
- столбец переименован в `DAY`;
|
||
- `ORDER BY "HIRE_DATE"` сортирует результаты по дате найма, от ранних к поздним.
|
||
|
||
Результат выполнения запроса представлен на рисунке 28.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/28.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
==== Задание 6. Составление запросов, требующих применения условных выражений.
|
||
|
||
===== 6.1 Создайте запрос, который позволяет для каждого служащего вывести фамилию и сумму комиссионных. Если служащий не зарабатывает комиссионных, укажите в столбце "No Commission". Назовите столбец COMM. Используются ф-ции преобразования типов и условное выражение COALESCE. Результат выполнения запроса должен быть схож с таблицей 25.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 2)[*LAST_NAME*][*COMM*][King][No Commission][Kochhar][No Commission][De Haan][No Commission][Hunold][No Commission][Ernst][No Commission][Lorentz][No Commission][Mourgos][No Commission][Rajs][No Commission][Davies][No Commission][Matos][No Commission][Vargas][No Commission][Zlotkey][0.20][Abel][0.30][$dots$][$dots$],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
```sql
|
||
SELECT
|
||
"LAST_NAME",
|
||
COALESCE(TO_CHAR("COMMISSION_PCT", 'FM0.00'), 'No Commission') AS "COMM"
|
||
FROM "EmployeesDepartments"."EMPLOYEES";
|
||
```
|
||
|
||
- `TO_CHAR("COMMISSION_PCT", 'FM0.00')` преобразует числовое значение комиссионных в текстовый формат с двумя десятичными знаками;
|
||
- `COALESCE(..., 'No Commission')` если значение комиссионных равно NULL, выводится строка 'No Commission';
|
||
- столбец переименован в `COMM`;
|
||
- вывод показывает фамилию сотрудника и либо его комиссионные, либо надпись 'No Commission'.
|
||
|
||
Результат выполнения запроса представлен на рисунке 29.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/29.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
===== 6.2 Создайте запрос, который позволяет для каждого служащего вывести должность и её разряда (grade), используя условное выражение CASE. Разряд каждого типа должности JOB_ID приведён в таблице 26, а результат выполнения запроса должен быть схож с таблицей 27.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 2)[*Должность*][*Разряд*][AD_PRES][E][ST_MAN][D][IT_PROG][C][SA_REP][B][ST_CLERK][A][Другая][0],
|
||
supplement: [Табл.],
|
||
caption: [Соответствие каждого типа должности и разряда.]
|
||
)
|
||
]
|
||
|
||
#align(center)[
|
||
#figure(
|
||
table(columns: 3)[*LAST_NAME*][*JOB_ID*][*GRADE*][King][AD_PRES][E][Kochhar][AD_VP][0][De Haan][AD_VP][0][Whalen][AD_ASST][0][Higgins][AC_MGR][0][Gietz][AC_ACCOUNT][0][Zlotkey][SA_MAN][0][Abel][SA_REP][B][Taylor][SA_REP][B][Grant][SA_REP][B][Mourgos][ST_MAN][D][Rajs][ST_CLERK][A][King][AD_PRES][E][Kochhar][AD_VP][0][De Haan][AD_VP][0][Whalen][AD_ASST][0][$dots$][$dots$][$dots$],
|
||
supplement: [Табл.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
|
||
```sql
|
||
SELECT
|
||
"JOB_ID" AS "Должность",
|
||
CASE "JOB_ID"
|
||
WHEN 'AD_PRES' THEN 'E'
|
||
WHEN 'ST_MAN' THEN 'D'
|
||
WHEN 'IT_PROG' THEN 'C'
|
||
WHEN 'SA_REP' THEN 'B'
|
||
WHEN 'ST_CLERK' THEN 'A'
|
||
ELSE '0'
|
||
END AS "GRADE"
|
||
FROM "EmployeesDepartments"."EMPLOYEES";
|
||
```
|
||
|
||
- `CASE ... WHEN ... THEN ... ELSE ... END` позволяет для каждого типа должности присвоить соответствующий разряд;
|
||
- должности, не указанные в таблице 26, получают разряд '0' через `ELSE '0'`;
|
||
- cтолбцы переименованы в `Должность` и `GRADE`;
|
||
|
||
Результат выполнения запроса представлен на рисунке 30.
|
||
|
||
#align(center)[
|
||
#figure(
|
||
image("assets/30.png"),
|
||
supplement: [Рис.],
|
||
caption: [Результат выполнения запроса.]
|
||
)
|
||
]
|
||
|
||
=== Выводы и анализ результатов работы
|
||
|
||
В ходе выполнения работы освоены конструкции SQL для работы с реляционными базами данных.
|
||
|
||
- Научился формировать запросы на выборку данных с использованием оператора `SELECT`
|
||
- Освоил использование `WHERE` для фильтрации данных по различным условиям
|
||
- Изучил применение `ORDER BY` для сортировки результатов запросов
|
||
- Научился использовать `DISTINCT` для выборки уникальных значений
|
||
- Освоил создание псевдонимов для столбцов с помощью `AS`
|
||
- Применил операторы сравнения
|
||
- Использовал логические операторы
|
||
- Освоил работу с операторами `BETWEEN`, `IN`, `NOT IN` для проверки диапазонов и списков значений
|
||
- Научился работать с `NULL` значениями через `IS NULL` и `IS NOT NULL`
|
||
- Применил оператор `LIKE` для поиска по шаблону в текстовых данных
|
||
- Освоил функции округления `ROUND()` для математических вычислений
|
||
- Научился выполнять арифметические операции в запросах
|
||
- Создавал вычисляемые поля для расчёта новых значений на основе существующих данных
|
||
- Применил функцию `CONCAT()` для объединения нескольких строковых значений
|
||
- Использовал `INITCAP()` для форматирования текста с заглавной первой буквой
|
||
- Освоил `LENGTH()` для определения длины строк
|
||
- Применил `SUBSTR()` для извлечения подстрок
|
||
- Научился использовать оператор конкатенации `||` в PostgreSQL
|
||
- Освоил функцию `CURRENT_DATE` для получения текущей системной даты
|
||
- Применил `EXTRACT()` для извлечения компонентов даты
|
||
- Использовал функцию `AGE()` для вычисления разницы между датами
|
||
- Научился форматировать даты с помощью `TO_CHAR()` для вывода дней недели
|
||
- Выполнил сложные вычисления с датами
|
||
- Освоил функцию `COALESCE()` для обработки `NULL` значений и замены их на заданные значения
|
||
- Применил конструкцию `CASE ... WHEN ... THEN ... ELSE ... END` для создания условной логики в запросах
|
||
- Научился создавать сложные поля с использованием множественных условий
|
||
|
||
В процессе выполнения работы возникли следующие сложности:
|
||
|
||
- При создании объектов с кавычками имена становятся регистрозависимыми.
|
||
|
||
- Получение названий дней недели на английском языке потребовало использования функции `TO_CHAR()`.
|