Да, для квалификационной работы лучше сделать не "на одной таблице всё", а нормально через связанные таблицы. Тогда и представление, и процедура, и триггер будут выглядеть профессионально.
Я бы делал так.
Таблицы
CREATE TABLE car_types (
type_id INT PRIMARY KEY AUTO_INCREMENT,
type_name VARCHAR(20) NOT NULL,
markup DECIMAL(10,2) NOT NULL
);
CREATE TABLE drivers (
driver_id INT PRIMARY KEY AUTO_INCREMENT,
phone VARCHAR(20) UNIQUE NOT NULL
);
CREATE TABLE cars (
car_id INT PRIMARY KEY AUTO_INCREMENT,
plate_number VARCHAR(10) UNIQUE NOT NULL,
type_id INT NOT NULL,
tariff_km DECIMAL(10,2) NOT NULL,
tariff_min DECIMAL(10,2) NOT NULL,
FOREIGN KEY (type_id)
REFERENCES car_types(type_id)
);
CREATE TABLE trips (
trip_id VARCHAR(10) PRIMARY KEY,
start_time DATETIME NOT NULL,
end_time DATETIME NOT NULL,
distance_km DECIMAL(10,2) NOT NULL,
travel_minutes INT,
trip_cost DECIMAL(10,2),
status ENUM('выполнена','отменена') NOT NULL,
driver_id INT NOT NULL,
car_id INT NOT NULL,
FOREIGN KEY (driver_id)
REFERENCES drivers(driver_id),
FOREIGN KEY (car_id)
REFERENCES cars(car_id)
);
---
Представление
Вывести:
авто
тип авто
номер водителя
количество поездок
общий километраж
общее время
Исключить отменённые.
CREATE VIEW vw_taxi_statistics AS
SELECT
c.plate_number AS auto_number,
ct.type_name AS auto_type,
d.phone AS driver_phone,
COUNT(t.trip_id) AS trips_count,
SUM(t.distance_km) AS total_km,
SUM(t.travel_minutes) AS total_minutes
FROM trips t
JOIN drivers d
ON t.driver_id = d.driver_id
JOIN cars c
ON t.car_id = c.car_id
JOIN car_types ct
ON c.type_id = ct.type_id
WHERE t.status = 'выполнена'
GROUP BY
c.plate_number,
ct.type_name,
d.phone;
---
Процедура с транзакцией
Стоимость:
км * тариф_за_км
+
минуты * тариф_за_минуту
+
наценка
DELIMITER $$
CREATE PROCEDURE CalculateTripCost(
IN p_trip_id VARCHAR(10)
)
BEGIN
DECLARE v_cost DECIMAL(10,2);
DECLARE v_status VARCHAR(20);
START TRANSACTION;
SELECT
(
t.distance_km * c.tariff_km
+
t.travel_minutes * c.tariff_min
+
ct.markup
),
t.status
INTO
v_cost,
v_status
FROM trips t
JOIN cars c
ON t.car_id = c.car_id
JOIN car_types ct
ON c.type_id = ct.type_id
WHERE t.trip_id = p_trip_id;
UPDATE trips
SET trip_cost = v_cost
WHERE trip_id = p_trip_id;
IF v_status = 'выполнена' THEN
COMMIT;
ELSE
ROLLBACK;
END IF;
END$$
DELIMITER ;
---
Триггер
Автоматически считает время поездки.
DELIMITER $$
CREATE TRIGGER trg_calc_minutes
BEFORE INSERT
ON trips
FOR EACH ROW
BEGIN
SET NEW.travel_minutes =
TIMESTAMPDIFF(
MINUTE,
NEW.start_time,
NEW.end_time
);
END$$
DELIMITER ;
---
Комментарий для защиты
Представление агрегирует информацию по выполненным поездкам и исключает отменённые.
Процедура принимает номер поездки, рассчитывает стоимость по тарифам автомобиля и наценке типа автомобиля, после чего сохраняет результат в таблицу. Используется транзакция.
Триггер автоматически вычисляет время поездки в минутах при добавлении новой записи.
Такое решение выглядит как полноценная БД в 3НФ и обычно соответствует требованиям квалификационной работы.