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


-- 1. Создание таблиц

-- Маршруты
CREATE TABLE маршруты (
    номер_маршрута SERIAL PRIMARY KEY,
    аэропорт_вылета VARCHAR(100) NOT NULL,
    аэропорт_назначения VARCHAR(100) NOT NULL,
    цена_билета_руб DECIMAL(10,2) NOT NULL CHECK (цена_билета_руб >= 0),
    продолжительность_полета_мин INTEGER NOT NULL CHECK (продолжительность_полета_мин > 0)
);

-- Самолеты
CREATE TABLE самолеты (
    бортовой_номер VARCHAR(20) PRIMARY KEY,
    модель VARCHAR(50) NOT NULL,
    дата_изготовления DATE NOT NULL,
    срок_эксплуатации_лет INTEGER NOT NULL CHECK (срок_эксплуатации_лет > 0),
    готовность_к_вылету BOOLEAN NOT NULL DEFAULT TRUE -- TRUE = Да, FALSE = Нет
);

-- Командиры корабля
CREATE TABLE командиры (
    личный_номер SERIAL PRIMARY KEY,
    фио VARCHAR(150) NOT NULL,
    адрес TEXT,
    телефон VARCHAR(20),
    налет_часов INTEGER NOT NULL CHECK (налет_часов >= 0)
);

-- Рейсы
CREATE TABLE рейсы (
    номер_рейса SERIAL PRIMARY KEY,
    номер_маршрута INTEGER NOT NULL,
    бортовой_номер VARCHAR(20) NOT NULL,
    дата_и_время_вылета TIMESTAMP NOT NULL,
    рейс_отменен BOOLEAN NOT NULL DEFAULT FALSE, -- TRUE = отменен, FALSE = не отменен
    FOREIGN KEY (номер_маршрута) REFERENCES маршруты(номер_маршрута) ON DELETE RESTRICT,
    FOREIGN KEY (бортовой_номер) REFERENCES самолеты(бортовой_номер) ON DELETE RESTRICT
);

-- Пассажиры
CREATE TABLE пассажиры (
    номер_паспорта VARCHAR(20) PRIMARY KEY,
    фио VARCHAR(150) NOT NULL,
    адрес TEXT,
    телефон VARCHAR(20)
);

-- Связь пассажиров и рейсов (билеты)
CREATE TABLE билеты (
    номер_паспорта VARCHAR(20) NOT NULL,
    номер_рейса INTEGER NOT NULL,
    PRIMARY KEY (номер_паспорта, номер_рейса),
    FOREIGN KEY (номер_паспорта) REFERENCES пассажиры(номер_паспорта) ON DELETE CASCADE,
    FOREIGN KEY (номер_рейса) REFERENCES рейсы(номер_рейса) ON DELETE CASCADE
);

-- Закрепление командиров за самолетами (один к одному)
-- У каждого самолета обязательно есть командир, командир закреплен за одним самолетом
ALTER TABLE самолеты ADD COLUMN личный_номер_командира INTEGER NOT NULL UNIQUE;
ALTER TABLE самолеты ADD FOREIGN KEY (личный_номер_командира) REFERENCES командиры(личный_номер) ON DELETE RESTRICT;

-- 2. Индексы для производительности (опционально)
CREATE INDEX idx_рейсы_маршрут ON рейсы(номер_маршрута);
CREATE INDEX idx_рейсы_самолет ON рейсы(бортовой_номер);
CREATE INDEX idx_рейсы_дата ON рейсы(дата_и_время_вылета);
CREATE INDEX idx_билеты_рейс ON билеты(номер_рейса);

-- 3. Пример вставки тестовых данных (можно удалить или изменить)

-- Командиры
INSERT INTO командиры (фио, адрес, телефон, налет_часов) VALUES
('Иванов Иван Иванович', 'Минск, ул. Ленина 1', '+375291234567', 3500),
('Петров Петр Петрович', 'Минск, ул. Гагарина 5', '+375292345678', 4200);

-- Самолеты (с привязкой к командирам)
INSERT INTO самолеты (бортовой_номер, модель, дата_изготовления, срок_эксплуатации_лет, готовность_к_вылету, личный_номер_командира) VALUES
('EW-101PA', 'Боинг-747', '2015-06-01', 25, TRUE, 1),
('EW-202TB', 'Ту-134', '2010-03-12', 30, TRUE, 2);

-- Маршруты
INSERT INTO маршруты (аэропорт_вылета, аэропорт_назначения, цена_билета_руб, продолжительность_полета_мин) VALUES
('Минск', 'Франкфурт', 250.00, 120),
('Минск', 'Рига', 180.00, 80);

-- Рейсы
INSERT INTO рейсы (номер_маршрута, бортовой_номер, дата_и_время_вылета, рейс_отменен) VALUES
(1, 'EW-101PA', '2025-05-20 08:30:00', FALSE),
(2, 'EW-202TB', '2025-05-20 14:15:00', FALSE);

-- Пассажиры
INSERT INTO пассажиры (номер_паспорта, фио, адрес, телефон) VALUES
('MP1234567', 'Сидоров Сидор Сидорович', 'Минск, ул. Красная 10', '+375293334455'),
('MP7654321', 'Кузнецова Анна Петровна', 'Брест, пр. Машерова 22', '+375256667788');

-- Билеты
INSERT INTO билеты (номер_паспорта, номер_рейса) VALUES
('MP1234567', 1),
('MP7654321', 1),
('MP7654321', 2);

-- 4. Представление (VIEW) для отображения РЕЙСОВ авторизованных ПАССАЖИРОВ
-- Под "авторизованных" обычно понимается конкретный пассажир по номеру паспорта
-- Создаем функцию, которая принимает номер паспорта и возвращает список рейсов этого пассажира

CREATE OR REPLACE FUNCTION рейсы_пассажира(p_номер_паспорта VARCHAR)
RETURNS TABLE (
    номер_рейса INTEGER,
    дата_и_время_вылета TIMESTAMP,
    рейс_отменен BOOLEAN,
    аэропорт_вылета VARCHAR,
    аэропорт_назначения VARCHAR,
    модель_самолета VARCHAR,
    фио_командира VARCHAR
) AS $$
BEGIN
    RETURN QUERY
    SELECT 
        р.номер_рейса,
        р.дата_и_время_вылета,
        р.рейс_отменен,
        м.аэропорт_вылета,
        м.аэропорт_назначения,
        с.модель AS модель_самолета,
        к.фио AS фио_командира
    FROM билеты б
    JOIN рейсы р ON б.номер_рейса = р.номер_рейса
    JOIN маршруты м ON р.номер_маршрута = м.номер_маршрута
    JOIN самолеты с ON р.бортовой_номер = с.бортовой_номер
    JOIN командиры к ON с.личный_номер_командира = к.личный_номер
    WHERE б.номер_паспорта = p_номер_паспорта
    ORDER BY р.дата_и_время_вылета;
END;
$$ LANGUAGE plpgsql;

-- Пример использования функции для пассажира с паспортом 'MP7654321'
-- SELECT * FROM рейсы_пассажира('MP7654321');