- •Введение
- •1 Описание предметной области
- •Определение сущностей и атрибутов
- •Описание источников информации для заполнения базы данных
- •Описание пользователей информационной системы
- •Анализ сущностей и связей между ними
- •Составление требуемых запросов к базе данных (на языке sql)
- •7 Создание пользователей и назначение ролей
- •Реализация триггеров
- •9 Разработка пользовательского интерфейса
- •10 Обработка и визуализация данных
- •Заключение
- •Список использованных источников
- •Приложение а. Наполнение таблиц базы данных
- •Приложение b. Создание графического интерфейса
Составление требуемых запросов к базе данных (на языке sql)
После заполнения таблиц данными составлены запросы на выборку данных из таблиц. Для удобства вызова запросы инкапсулированы в хранимые процедуры MySQL [3].
Первый запрос выводит список спортивных сооружений определенного типа или определенной характеристики. Запрос помогает определить сооружения, подходящие для проведения мероприятий определенного масштаба. Информация из запроса может быть полезна организаторам соревнований. Так как входные значения вводит пользователь, то предусмотрена проверка на корректность вводимых значений, если данные не корректны, происходит вызов исключения с помощью оператора SIGNAL [4]. Это помогает обеспечить безопасность выполнения запроса и предотвращает возможные ошибки
Выборка выполняется с использованием оператора SELECT [5]. Для объединения данных из разных таблиц используется оператор JOIN [6]. Это позволяет получить информацию о сооружениях и их характеристиках, хранящуюся в разных таблицах. Для выборки только нужных данных используется условие WHERE [7].
Листинг 1- Процедура на вывод списка спортивных сооружений определенного типа или определенной характеристики
DELIMITER //
CREATE PROCEDURE Get_sport_constructions (
IN Характеристика VARCHAR(20),
IN ЗначениеХарактеристики VARCHAR(20)
)
BEGIN
IF NOT (Характеристика IN ('Тип', 'Вместимость', 'Покрытие')) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Неверное значение Характеристики';
END IF;
IF Характеристика = 'Тип' AND NOT EXISTS (SELECT 1 FROM Спортивные_сооружения WHERE Тип = ЗначениеХарактеристики) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Значение Характеристики не существует в таблице Спортивные_сооружения';
END IF;
IF Характеристика = 'Покрытие' AND NOT EXISTS (SELECT 1 FROMТипы_спортивных_сооружений WHERE Покрытие = ЗначениеХарактеристики) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Значение Характеристики не существует в таблице Спортивные_сооружения';
END IF;
SELECT
s.Код_спортивного_сооружения,
s.Тип,
t.Вместимость,
t.Покрытие
FROM
Спортивные_сооружения s
JOIN
Типы_спортивных_сооружений t ON s.Код_типа_спортивного_сооружения = t.Код_типа
WHERE
(Характеристика = 'Тип' AND s.Тип >= ЗначениеХарактеристики) OR
(Характеристика = 'Вместимость' AND t.Вместимость >= ЗначениеХарактеристики) OR
(Характеристика = 'Покрытие' AND t.Покрытие = ЗначениеХарактеристики);
END //
DELIMITER ;
На рисунке 1 показан результат вывода списка спортивных сооружений при задании характеристики вместимости больше 40.
Рисунок 2- Результат вывода процедуры Get_sport_constructions
Также было задано значение характеричтики, которого не существует в таблице (Рисунок 3).
Рисунок 3-Вывод сообщения об ошибке
Рисунок 4-Таблица Спортивные_сооружения
Рисунок 5-Таблица Типы_спортивных_сооружений
Второй запрос позволяет получить список спортсменов, которые тренируются у конкретного тренера, и у которых разряд не ниже определенного. Произведена проверка входнных значений.
Листинг 2- Процедура на вывод списка спортсменов, тренирующихся у оепрделнного тернера, и у которых не ниже определенного разряда
DELIMITER //
CREATE PROCEDURE Get_athletes_by_coach_and_rank (
IN coach_surname VARCHAR(20),
IN min_rank INT
)
BEGIN
DECLARE coach_exists INT;
SELECT COUNT(*) INTO coach_exists
FROM Тренеры
WHERE Фамилия = coach_surname;
IF coach_exists = 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Тренер с указанной фамилией не найден';
END IF;
IF min_rank < 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Разряд не может быть отрицательным';
END IF;
SELECT
s.Код_спортсмена AS Код_спортсмена,
s.Имя AS Имя,
s.Фамилия AS Фамилия,
s.Код_спортивного_клуба AS Код_спортивного_клуба,
s.Разряд AS Разряд,
c.Фамилия AS Тренер
FROM
Спортсмены s
JOIN
Тренировки t ON s.Код_спортсмена = t.Код_спортсмена
JOIN
Тренеры c ON t.Код_тренера = c.Код_тренера
WHERE
c.Фамилия = coach_surname
AND s.Разряд <= min_rank;
END //
DELIMITER ;
Выведен список спортсменов, которые тренируются у тренера с фамилией «Катаева», и у которых разряд не меньше второго (Рисунок 6).
Рисунок 6- Выполнение запроса на выборку спортсменов
Введена фамилия тренера, которой не существует в таблице (Рисунок 7).
Рисунок 7- Вывод ошибки из-за ввода несуществующих данных
Рисунок 8- Тыблица Тренеры
Рисунок 9- Таблица Спортсмены
Рисунок 10- Таблица тренировки
Третий запрос помогает выявить спортсменов, которые занимаются несколькими видами спорта (Рисунок 11). Это может быть полезной информацией для тренеров и спортсменов, позволяя им адаптировать тренировочные программы.
С помощью оператора COUNT() подсчитывается количество видов спорта, которыми занимается каждый спортсмен [8]. HAVING фильтрует спортсменов, которые занимаются более чем одним видом спорта [9]. Кроме столбца с количеством видов спорта, выводится столбец с названиями этих видов, для этого использовался оператор GROUP_CONCAT, который объединяет значения из нескольких строк в одну строку [10].
Листинг 3- Процедура на вывод списка спортсменов, которые занимаются несколькими видами спорта
DELIMITER //
CREATE PROCEDURE Get_athletes_multiple_sports ()
BEGIN
SELECT
s.Код_спортсмена AS Код_спортсмена,
s.Имя AS Имя,
s.Фамилия AS Фамилия,
COUNT(DISTINCT t.Код_вида_спорта) AS Количество_видов_спорта,
GROUP_CONCAT(DISTINCT v.Название ORDER BY v.Название SEPARATOR ', ') AS Виды_спорта
FROM
Спортсмены s
JOIN
Тренировки tr ON s.Код_спортсмена = tr.Код_спортсмена
JOIN
Тренеры t ON tr.Код_тренера = t.Код_тренера
JOIN
Виды_спорта v ON t.Код_вида_спорта = v.Код_вида_спорта
GROUP BY
s.Код_спортсмена,
s.Имя,
s.Фамилия
HAVING
COUNT(DISTINCT t.Код_вида_спорта) > 1;
END //
DELIMITER ;
CALL Get_athletes_multiple_sports();
Риснуок 11- Список спортсменов, которые занимаютмя более, чем одним видом спорта
Рисунок 12- Таблица Виды_спорта
Четвертый запрос предоставляет информацию о соревнованиях, которые прошли за определенный период времени или были организованы конкретным организатором. Это может быть полезно для планирования расписания соревнований и оценки активности организаторов в спортивной области. Выполняется проверка на то, что дата начала соревнований не позже даты окончания.
Листинг 4- Процедура на вывод списка соревнований, прошедших за определенный период или организованным конкретным организатором
DELIMITER //
CREATE PROCEDURE Get_competitions (
IN start_date DATETIME,
IN end_date DATETIME,
IN organizator VARCHAR(20)
)
BEGIN
DECLARE org_exists INT;
SELECT COUNT(*) INTO org_exists
FROM Организаторы
WHERE Фамилия = organizator;
IF org_exists = 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Организатор с указанной фамилией не найден';
END IF;
IF start_date > end_date THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Дата начала не может быть позже даты окончания';
END IF;
SELECT
c.Код_соревнования AS Код_соревнования,
c.Дата_проведения AS Дата_проведения,
s.Название AS Название_вида_спорта,
o.Фамилия AS Фамилия_организатора
FROM
Соревнования c
JOIN
Виды_спорта s ON c.Код_вида_спорта = s.Код_вида_спорта
JOIN
Организаторы o ON c.Код_организатора = o.Код_организатора
WHERE
(c.Дата_проведения BETWEEN start_date AND end_date)
OR (o.Фамилия = organizator);
END //
DELIMITER ;
Выполнен запрос на выборку по датам начала и окончания соревнований (Рисунок 13) и по заданному идентификатору организатора (Рисунок 14).
Рисунок 13- Вывод списка соревнований, прошедших за определенный период времени
Рисунок 14- Вывод списка соревнований, организованных определенным организаторм
Рисунок 15- Таблица Организаторы
Рисунок 16- Таблица Соревнования
Пятый запрос позволяет получить список спортсменов, занявших призовые места на конкретном соревновании (Рисунок 17). Это полезная информация для тех, кто интересуется результатами соревнований. Произведена проверка на существование соревнования (Рисунок 18).
Листинг 5- Процедура на вывод списка спортсменов, занявших призовые места на конкретном соревновании
DELIMITER //
CREATE PROCEDURE Get_winners_by_competition (
IN competition_id INT
)
BEGIN
DECLARE competition_exists INT;
SELECT COUNT(*) INTO competition_exists
FROM Соревнования
WHERE Код_соревнования = competition_id;
IF competition_exists = 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Соревнование с указанным идентификатором не найдено';
END IF;
SELECT
s.Код_спортсмена AS Код_спортсмена,
s.Имя AS Имя,
s.Фамилия AS Фамилия,
s.Разряд AS Разряд,
aw.Тип AS Тип_награды
FROM
Награды aw
JOIN
Спортсмены s ON aw.Код_спортсмена = s.Код_спортсмена
WHERE
aw.Код_соревнования = competition_id;
END //
DELIMITER ;
Рисунок 17- Вывод списка призеров соревнования с идентификатором 1
Рисунок 18- Ввод несуществующего знаяения идентификатора соревновнвания
Рисунок 19- Таблица Награды
Шестой запрос позволяет получить информацию о соревнованиях, которые проходили в конкретном спортивном сооружении или по определенному виду спорта. Это может быть полезно при планировании мероприятий.
Листинг 6- Процедура на вывод списка соревнований, которые проходили конкретном спортивном сооружении или по определенному виду спорта
DELIMITER //
CREATE PROCEDURE Get_competitions_by_constructions_or_sport (
IN constructions_id INT,
IN sport_id INT
)
BEGIN
DECLARE constructions_exists INT;
DECLARE sport_exists INT;
IF constructions_id IS NOT NULL THEN
SELECT COUNT(*) INTO constructions_exists
FROM Спортивные_сооружения
WHERE Код_спортивного_сооружения = constructions_id;
IF constructions_exists = 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Спортивное сооружение с указанным идентификатором не найдено';
END IF;
END IF;
IF sport_id IS NOT NULL THEN
SELECT COUNT(*) INTO sport_exists
FROM Виды_спорта
WHERE Код_вида_спорта = sport_id;
IF sport_exists = 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Вид спорта с указанным идентификатором не найден';
END IF;
END IF;
SELECT
c.Код_соревнования AS Код_соревнования,
c.Дата_проведения AS Дата_проведения,
s.Код_вида_спорта AS Код_вида_спорта,
c.Код_спортивного_сооружения AS Код_спортивного_сооружения,
ss.Тип AS Тип_спортивного_сооружения,
o.Фамилия AS Фамилия_организатора
FROM
Соревнования c
JOIN
Виды_спорта s ON c.Код_вида_спорта = s.Код_вида_спорта
JOIN
Спортивные_сооружения ss ON c.Код_спортивного_сооружения = ss.Код_спортивного_сооружения
JOIN
Организаторы o ON c.Код_организатора = o.Код_организатора
WHERE
(constructions_id IS NULL OR c.Код_спортивного_сооружения = constructions_id)
AND
(sport_id IS NULL OR c.Код_вида_спорта = sport_id);
END //
DELIMITER ;
На рисунка 20 -23 представлена работа процедуры для разных входных данных.
Рисунок 20- Вывод списка соревнований проходивших на втором спортивном сооружении
Рисунок 21- Вывод списка соревнований, проходивших по виду спорта с идентификатором 2
Рисунок 22- Вывод списка соревнований, проходивших на втором сооружении по виду спорта с идентификатором 4
Седьмой запрос выводит список организаторов соревнований и число проведенных ими соревнований. Этот запрос предоставляет данные для анализа активности и влияния различных организаторов на спортивную сферу.
Используется оператор LEFT JOIN, который возвращает все строки из таблицы Организаторы даже, если их нет в таблице Соревнования, со значением количества соревнований NULL [11]. Это поможет отследить организаторов, которые не устраивали ни одного соревнования.
Листинг 7- Процедура на вывод списка организаторов соревнований и число проведенных ими соревнований
DELIMITER //
CREATE PROCEDURE Get_organizers_and_competition_count ()
BEGIN
SELECT
o.Код_организатора AS Код_организатора,
o.Имя AS Имя,
o.Фамилия AS Фамилия,
COUNT(c.Код_соревнования) AS Количество_соревнований
FROM
Организаторы o
LEFT JOIN
Соревнования c ON o.Код_организатора = c.Код_организатора
GROUP BY
o.Код_организатора,
o.Имя,
o.Фамилия
ORDER BY
Количество_соревнований DESC;
END //
DELIMITER ;
Рисунок 23- Вывод списка организаторов соревнований и число проведенных ими соревнований
Восьмой запрос выводит cписок спортивных сооружений, где проходили соревнования по определенному виду спорта, с детализацией по количеству соревнований (Рисунок 24). Предусмотрен вывод сообщения об ошибке при вводе несуществующего идентификатора вида спорта (Рисунок 25).
Листинг 8- Процедура на вывод списка спортивных сооружений, где проходили соревнования по определенному виду спорта
DELIMITER //
CREATE PROCEDURE Get_constructions_by_sport (
IN sport_id INT
)
BEGIN
DECLARE sport_exists INT;
SELECT COUNT(*) INTO sport_exists
FROM Виды_спорта
WHERE Код_вида_спорта = sport_id;
IF sport_exists = 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Вид спорта с указанным идентификатором не найден';
END IF;
SELECT
ss.Код_спортивного_сооружения AS Код_спортивного_сооружения,
ss.Тип AS Тип_спортивного_сооружения,
COUNT(c.Код_соревнования) AS Количество_соревнований
FROM
Спортивные_сооружения ss
JOIN
Соревнования c ON ss.Код_спортивного_сооружения = c.Код_спортивного_сооружения
WHERE
c.Код_вида_спорта = sport_id
GROUP BY
ss.Код_спортивного_сооружения,
ss.Тип
ORDER BY
Количество_соревнований DESC;
END //
DELIMITER ;
Рисунок 24- Вывод списка спортивных сооружений, где проходили соревнования по виду спорта с идентификатором 5
Рисунок 25- Вывод сообщения об ошибке о несуществующем идентификаторе вида спорта
Девятый запрос вывод список тренеров, спортсмены которых участвовали в соревнованиях, проведенных определенными организаторами, с суммарным количеством наград.
Листинг 9- Процедура на вывод списка тренеров, спортсмены которых участвовали в соревнованиях, проведенных определенными организаторами (Рисунок 26-27).
DELIMITER //
CREATE PROCEDURE Get_trainers_with_athlete_awards_by_organizators (
IN organizator_id INT
)
BEGIN
SELECT
t.Код_тренера AS Код_тренера,
t.Имя AS Имя,
t.Фамилия AS Фамилия,
COUNT(n.Код_награды) AS Количество_наград
FROM
Тренеры t
LEFT JOIN
Тренировки tr ON t.Код_тренера = tr.Код_тренера
JOIN
Спортсмены s ON tr.Код_спортсмена = s.Код_спортсмена
JOIN
Награды n ON s.Код_спортсмена = n.Код_спортсмена
JOIN
Соревнования c ON n.Код_соревнования = c.Код_соревнования
WHERE
c.Код_организатора = organizator_id
GROUP BY
t.Код_тренера,
t.Имя,
t.Фамилия
ORDER BY
Количество_наград DESC;
END //
DELIMITER ;
Рисунок 26 – Вывод списка тренеров, спортсмены которых участвовали в соревнованиях, проведенных организатором с идентификатором 2
Рисунок 27 – Вывод списка тренеров, спортсмены которых участвовали в соревнованиях, проведенных организатором с идентификатором 3
Десятый запрос выводит список всех тренеров вместе с количеством их спортсменов, средним количеством наград на спортсмена, и общим количеством соревнований, в которых участвовали их спортсмены. Результаты отфильтрованы так, чтобы включать только тех тренеров, чьи спортсмены выиграли хотя бы одну награду в текущем году (Рисунок 28).
Листинг 10- Процедура на вывод списка тренеров с детализацией по спортсменам
DELIMITER //
CREATE PROCEDURE Get_trainers_with_athlete_status_for_current_year ()
BEGIN
DECLARE current_year INT;
SET current_year = YEAR(CURDATE());
SELECT
t.Код_тренера AS Код_тренера,
t.Имя AS Имя,
t.Фамилия AS Фамилия,
COUNT(DISTINCT s.Код_спортсмена) AS Количество_спортсменов,
ROUND(AVG(awards_per_athlete.Награды_на_спортсмена),1) AS Среднее_количество_наград_на_спортсмена,
COUNT(DISTINCT c.Код_соревнования) AS Общее_количество_соревнований
FROM
Тренеры t
JOIN
Тренировки tr ON t.Код_тренера = tr.Код_тренера
JOIN
Спортсмены s ON tr.Код_спортсмена = s.Код_спортсмена
LEFT JOIN
(SELECT
n.Код_спортсмена,
COUNT(n.Код_награды) AS Награды_на_спортсмена
FROM
Награды n
JOIN
Соревнования c ON n.Код_соревнования = c.Код_соревнования
WHERE
YEAR(c.Дата_проведения) = current_year
GROUP BY
n.Код_спортсмена) AS awards_per_athlete ON s.Код_спортсмена = awards_per_athlete.Код_спортсмена
JOIN
Награды n ON s.Код_спортсмена = n.Код_спортсмена
JOIN
Соревнования c ON n.Код_соревнования = c.Код_соревнования
WHERE
YEAR(c.Дата_проведения) = current_year
GROUP BY
t.Код_тренера,
t.Имя,
t.Фамилия
HAVING
COUNT(awards_per_athlete.Награды_на_спортсмена) > 0
ORDER BY
Код_тренера;
END //
DELIMITER ;
CALL Get_trainers_with_athlete_status_for_current_year();
Рисунок 28 – Вывод списка тренеров с детализацией по спортсменам
