Добавил:
ИВТ (советую зайти в "Несортированное") Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
30
Добавлен:
19.09.2024
Размер:
1.66 Mб
Скачать
  1. Практическая часть

Вариант к практической части выбирается по формуле: V = (N % 10) +1, где N – номер в списке группы, % - остаток от деления.

    1. Задание 1

Исследование типов данных

Предположим, что в магазине новый конструктор стоит 999 рублей и 99 копеек. Студент С. решил приобрести для дальнейшей перепродажи 100000 таких товаров. Для расчета общей суммы, которую необходимо заплатить был создан следующий скрипт на языке PL/pgSQL. Более подробно о нём будет рассказано в одной из следующих лабораторных работ. Обратите внимание, что значение суммы имеет тип real.

DO

$$

DECLARE

summ real :=0.0;

BEGIN

FOR i IN 1..100000 LOOP

summ := summ + 999.99;

END LOOP;

RAISE NOTICE 'Summ = %;', summ;

--RAISE NOTICE 'Diff = %;', 99999000.00 - summ;

END

$$ language plpgsql;

Запустите скрипт. Раскомментируйте строку с вычислением разницы и определите, сколько денег переплатил студент С? Объясните полученный результат. Измените тип суммы на numeric и money. Какой результат был получен в обоих случаях?

ключевое слово DECLARE используется для объявления курсора внутри блока PL/pgSQL (например, в функции или процедуре). Курсор позволяет управлять набором данных, извлекаемым из таблиц, по одной строке за раз, вместо получения всех строк сразу.

DECLARE используется для объявления переменной summ, которая будет хранить промежуточные результаты сложения.

RAISE NOTICE 'Summ = %;', summ;:

  • Команда RAISE NOTICE выводит промежуточный результат на экран или в лог. В данном случае выводится итоговая сумма summ, которая вычисляется после завершения цикла.

Этот скрипт выполняет простое сложение чисел в цикле 100 000 раз, прибавляя к переменной summ число 999.99 на каждой итерации. Однако точность вычислений зависит от типа данных, используемого для переменной summ. В изначальном варианте тип данных real может вызывать погрешности из-за ограничения точности представления чисел с плавающей запятой.

Видим, что это экпоненциальное отображение числа (т.е 9,999999 * 10^7)

Достаточно неточно

DIFF – те ушел в минус на 992 условных едениц (переплата)

Тип numeric указывает, что переплаты нет (нет погрешности)

Изменил тип данных на money и у цифр на ::money, а также добавил запятые т.к это денежный тип данных (переплаты тоже нет), а также вывод данных приятнее. (погрешности нет)

Вывод:

  • real может привести к ошибкам из-за округления.

  • numeric предоставляет точные результаты.

  • money работает с округлением и обеспечивает удобство для финансовых операций, но точность может быть ниже, чем у numeric.

    1. Задание 2

Написание запросов на языке SQL

Вар 1

1, 11, 21, 31, 41, 51, 61, 71

Напишите SQL запросы к учебной базе данных в соответствии с вариантом. Запросы брать из сборник запросов к учебной базе данных, расположенного ниже

Сборник запросов к учебной базе данных

Условия WHERE, ORDER BY

  1. Вывести всех студентов группы отсортировав по возрасту

SELECT students_group_number,age (CURRENT_DATE,birthday),last_name,first_name,patronymic

FROM students

WHERE students_group_number = 'ИВТ-43'

ORDER BY age ASC; -- sortirovka po vozrast up

--AND last_name LIKE '%'

--AND patronymic LIKE '%'

--AND first_name LIKE '%';

  1. Вывести список всех предметов, отсортировав по уникальному Id

SELECT field_id, field_name

FROM fields

GROUP BY field_id – можно было написать просто WHERE field_id LIKE ‘%’

ORDER BY field_id ASC;

Решил по возрастанию ( с 0 – до Z)

Группировка GROUP BY

  1. Подсчитать количество двоечников, троечников, хорошистов и отличников среди студентов.

Именно по предмету! Всего 24999 студента и сумма сходится

SELECT

CASE

WHEN mark =2 THEN 'Двоечники'

WHEN mark =3 THEN 'Троечники'

WHEN mark =4 THEN 'Хорошисты'

WHEN mark =5 THEN 'Отличники'

END AS категория,

COUNT(*) AS количество_студентов

FROM field_comprehensions -- таблица с оценками

GROUP BY

CASE

WHEN mark =2 THEN 'Двоечники'

WHEN mark =3 THEN 'Троечники'

WHEN mark =4 THEN 'Хорошисты'

WHEN mark =5 THEN 'Отличники'

END;

  1. Подсчитать количество должников по каждой дисциплине и вывести на экран код дисциплины и количество должников, превышающих 50 человек.

Я так понял, что debtor_students (задание некоректно) или же field_comprehensions (сделаю по второму файлу, где долг у тех, кто не пришел на экз и те у кого 2)

SELECT field,COUNT(*) AS kolvo_dolg

FROM field_comprehensions

WHERE mark <3

GROUP BY field

HAVING COUNT(*) > 50; -- POKAZ GDE >50

Регулярные выражения

  1. Вывести весь 3-й курс ИБ, отсортировать по возрасту

SELECT *, age(CURRENT_DATE,birthday)

FROM students

WHERE students_group_number LIKE 'ИБ-3%'

ORDER BY age ASC;

  1. Вывести всех студентов, родившихся зимой, используя регулярные выражения

SELECT *

FROM students

WHERE TO_CHAR(birthday, 'MM') ~ '^(01|02|12)$';

TO_CHAR(birthday, 'MM') — преобразует дату в строку, которая содержит только месяц в формате двух цифр (MM).

~ '^(01|02|12)$' — регулярное выражение, которое проверяет, соответствует ли месяц значениям "01" (январь), "02" (февраль) или "12" (декабрь).

Общее

  1. Выведите фамилии и количество их повторений, которые начинаются на ту же

букву, что и ваша фамилия, а две последние буквы фамилии с вашей не совпадают.

SELECT last_name, COUNT(*) AS count

FROM students

WHERE last_name LIKE 'Б%'

AND last_name NOT LIKE '%ов'

GROUP BY last_name;

  1. Подсчитать количество студентов, родившихся раньше '01/01/2004' в каждой группе, вывести названия и количество студентов тех групп, в которых таких студентов больше 20. Отсортировать по количеству. Всем столбцам дать русские имена.

Раньше НЕ включительно

SELECT students_group_number AS группа,COUNT(*) AS колво

FROM students

WHERE TO_CHAR(birthday,'YY')~'^(05|06|07|08|09|1[0-9])$'

GROUP BY students_group_number

HAVING COUNT(*) > 20

ORDER BY колво DESC;

    1. Задание 3

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

(колво студентов в группе)

SELECT

students_group_number AS "Номер группы",

COUNT(*) AS "Количество студентов"

FROM

students

GROUP BY

students_group_number

ORDER BY

"Количество студентов" DESC;

(Средняя оценка)

SELECT

field_id AS "Код дисциплины",

AVG(mark) AS "Средняя оценка"

FROM

field_comprehensions

GROUP BY

field_id

ORDER BY

"Средняя оценка" DESC;

(Студенты с оценками ниже 3 по дисциплине 'Математика')

SELECT

student_id AS "ID студента",

mark AS "Оценка"

FROM

field_comprehensions

WHERE

field_id IN (

SELECT field_id

FROM fields

WHERE field_name = 'Математика'

)

AND mark < 3;

Дата рождения студентов, родившихся в зимние месяцы (декабрь, январь, февраль)

SELECT

last_name AS "Фамилия",

first_name AS "Имя",

birthday AS "Дата рождения"

FROM

students

WHERE

TO_CHAR(birthday, 'MM') IN ('12', '01', '02');

Фамилии студентов, имеющих оценки ниже 3 по как минимум одной дисциплине

SELECT DISTINCT

student_id AS "ID студента"

FROM

field_comprehensions

WHERE

mark < 3;

Группы студентов с количеством студентов, родившихся до 1 января 2000 года, превышающим 10 человек

SELECT

students_group_number AS "Номер группы",

COUNT(*) AS "Количество студентов"

FROM

students

WHERE

birthday < '2000-01-01'

GROUP BY

students_group_number

HAVING

COUNT(*) > 10

ORDER BY

"Количество студентов" DESC;

Студенты, не сдавшие ни одну дисциплину (т.е. нет записей в field_comprehensions

SELECT

student_id AS "ID студента"

FROM

students

WHERE

student_id NOT IN (

SELECT DISTINCT student_id

FROM field_comprehensions

);

Соседние файлы в папке 2 лр