Загрузка данных


Да, для квалификационной работы лучше сделать не "на одной таблице всё", а нормально через связанные таблицы. Тогда и представление, и процедура, и триггер будут выглядеть профессионально.

Я бы делал так.

Таблицы

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НФ и обычно соответствует требованиям квалификационной работы.