123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707 |
- CREATE OR REPLACE VIEW user_error_stats AS
- WITH measurement_counts AS (
- -- CTE для подсчета общего количества измерений
- SELECT
- COUNT(*) AS count,
- user_id
- FROM public.measurement_params AS t1
- INNER JOIN public.measurement_batch AS t2 ON t2.measurement_param_id = t1.id
- GROUP BY user_id
- ),
- error_counts AS (
- -- CTE для подсчета количества ошибочных данных
- SELECT
- COUNT(*) AS error_count,
- user_id
- FROM public.measurement_params AS t1
- INNER JOIN public.measurement_batch AS t2 ON t2.measurement_param_id = t1.id
- WHERE (public.fn_check_params(height, temperature, pressure, wind_direction, wind_speed, bullet_speed)::public.check_result).is_check = False
- GROUP BY user_id
- )
- -- Основной запрос, использующий CTE
- SELECT
- t1.name AS user_name,
- t2.name AS position,
- COALESCE(mc.count, 0) AS count,
- COALESCE(fc.error_count, 0) AS error_count
- FROM public.employees AS t1
- INNER JOIN public.ranks AS t2 ON t1.rank_id = t2.id
- LEFT JOIN measurement_counts AS mc ON mc.user_id = t1.id
- LEFT JOIN error_counts AS fc ON fc.user_id = t1.id
- ORDER BY fc.error_count DESC;
- --Таблица 3
- -- Создаем таблицу speed_of_average_wind с внешним ключом на calc_height_correction.id
- CREATE TABLE speed_of_average_wind
- (
- height_id INTEGER PRIMARY KEY REFERENCES calc_height_correction(id), -- Внешний ключ на calc_height_correction
- distance NUMERIC[], -- Массив для отрицательных значений
- degree INTEGER
- );
- -- Вставляем данные в таблицу speed_of_average_wind, используя id из calc_height_correction
- INSERT INTO CREATE OR REPLACE VIEW employee_measurement_stats AS
- WITH measurement_counts AS (
- -- CTE для подсчета общего количества измерений
- SELECT
- COUNT(*) AS count,
- user_id
- FROM public.measurment_input_params AS t1
- INNER JOIN public.measurment_baths AS t2 ON t2.measurment_input_param_id = t1.id
- GROUP BY user_id
- ),
- error_counts AS (
- -- CTE для подсчета количества ошибочных данных
- SELECT
- COUNT(*) AS fail_count,
- user_id
- FROM public.measurment_input_params AS t1
- INNER JOIN public.measurment_baths AS t2 ON t2.measurment_input_param_id = t1.id
- WHERE (public.fn_check_input_params(height, temperature, pressure, wind_direction, wind_speed, bullet_demolition_range)::public.check_result).is_check = False
- GROUP BY user_id
- )
- -- Основной запрос, использующий CTE
- SELECT
- t1.name AS user_name,
- t2.description AS position,
- COALESCE(mc.count, 0) AS count,
- COALESCE(fc.fail_count, 0) AS fail_count
- FROM public.employees AS t1
- INNER JOIN public.ranks AS t2 ON t1.rank_id = t2.id
- LEFT JOIN measurement_counts AS mc ON mc.user_id = t1.id
- LEFT JOIN error_counts AS fc ON fc.user_id = t1.id
- ORDER BY fc.fail_count DESC;
- CREATE TABLE calculation_logs (
- id SERIAL PRIMARY KEY,
- input_params JSONB NOT NULL, -- Входные параметры расчета
- input_params_hash VARCHAR(32) NOT NULL, -- Хэш входных параметров
- used_table_values JSONB, -- Использованные значения из таблиц с корректировкой
- intermediate_results JSONB, -- Промежуточные результаты
- calculation_result JSONB, -- Итоговый результат расчета
- calculation_timestamp TIMESTAMP DEFAULT NOW() -- Время выполнения расчета
- );
- CREATE UNIQUE INDEX idx_calculation_logs_input_params_hash ON calculation_logs (input_params_hash);
- CREATE OR REPLACE FUNCTION log_calculation(input_params JSONB, used_table_values JSONB, intermediate_results JSONB, calculation_result JSONB) RETURNS VOID AS $$
- DECLARE
- input_params_hash TEXT;
- BEGIN
- -- Генерация хэша входных параметров
- input_params_hash := md5(input_params::text);
- -- Проверка, был ли уже выполнен расчет с такими параметрами
- IF EXISTS (SELECT 1 FROM calculation_logs WHERE input_params_hash = input_params_hash) THEN
- RAISE NOTICE 'Расчет с такими входными параметрами уже был выполнен';
- ELSE
- -- Логирование нового расчета
- INSERT INTO calculation_logs (input_params, input_params_hash, used_table_values, intermediate_results, calculation_result)
- VALUES (input_params, input_params_hash, used_table_values, intermediate_results, calculation_result);
- RAISE NOTICE 'Расчет успешно залогирован';
- END IF;
- END;
- $$ LANGUAGE plpgsql;
- --Таблица 3
- -- Создаем таблицу speed_of_average_wind с внешним ключом на calc_height_correction.id
- CREATE TABLE speed_of_average_wind
- (
- height_id INTEGER PRIMARY KEY REFERENCES calc_height_correction(id), -- Внешний ключ на calc_height_correction
- distance NUMERIC[], -- Массив для отрицательных значений
- degree INTEGER
- );
- -- Вставляем данные в таблицу speed_of_average_wind, используя id из calc_height_correction
- INSERT INTO speed_of_average_wind (height_id, distance, degree)
- VALUES
- ((SELECT id FROM calc_height_correction WHERE height = 200), ARRAY[3,4,5,6,7,7,8,9,10,11,12,12], 0),
- ((SELECT id FROM calc_height_correction WHERE height = 400), ARRAY[4,5,6,7,8,9,10,11,12,13,14,15], 1),
- ((SELECT id FROM calc_height_correction WHERE height = 800), ARRAY[4,5,6,7,8,9,10,11,13,14,15,16], 2),
- ((SELECT id FROM calc_height_correction WHERE height = 1200), ARRAY[4,5,6,7,8,9,10,11,12,13,14,15,16], 2),
- ((SELECT id FROM calc_height_correction WHERE height = 1600), ARRAY[4,6,7,8,9,10,11,13,14,15,17,17], 3),
- ((SELECT id FROM calc_height_correction WHERE height = 2000), ARRAY[4,6,7,8,9,10,11,13,14,16,17,18], 3),
- ((SELECT id FROM calc_height_correction WHERE height = 2400), ARRAY[4,6,8,9,9,10,12,14,15,16,18,19], 3),
- ((SELECT id FROM calc_height_correction WHERE height = 3000), ARRAY[5,6,8,9,10,11,12,14,15,17,18,19], 4),
- ((SELECT id FROM calc_height_correction WHERE height = 4000), ARRAY[5,6,8,9,10,11,12,14,16,18,19,20], 4);
- CREATE OR REPLACE FUNCTION calculate_average_wind_speed(
- par_height NUMERIC,
- par_bullet_demolition_range NUMERIC
- ) RETURNS NUMERIC AS $$
- DECLARE
- var_speed NUMERIC := 0;
- var_distance_index INT;
- var_distance_values NUMERIC[];
- BEGIN
- -- Если дальность сноса меньше 40 метров, скорость ветра равна 0
- IF par_bullet_demolition_range < 40 THEN
- RETURN 0;
- END IF;
- -- Получаем данные из таблицы для заданной высоты
- SELECT distance
- INTO var_distance_values
- FROM speed_of_average_wind
- WHERE height = par_height;
- -- Если данные для высоты не найдены, возвращаем 0
- IF var_distance_values IS NULL THEN
- RETURN 0;
- END IF;
- -- Вычисляем индекс на основе дальности сноса
- var_distance_index := LEAST(GREATEST((par_bullet_demolition_range - 40) / 10, 0), array_length(var_distance_values, 1) - 1);
- -- Получаем скорость ветра по индексу
- var_speed := var_distance_values[var_distance_index + 1]; -- Индексы в массиве начинаются с 1
- RETURN var_speed;
- END;
- $$ LANGUAGE plpgsql;
- CREATE OR REPLACE FUNCTION calculate_average_wind_direction(
- par_height NUMERIC,
- par_ground_wind_direction NUMERIC
- ) RETURNS NUMERIC AS $$
- DECLARE
- var_direction_increment NUMERIC;
- BEGIN
- -- Получаем приращение направления ветра из таблицы
- SELECT degree
- INTO var_direction_increment
- FROM speed_of_average_wind
- WHERE height = par_height;
- -- Если данные для высоты не найдены, возвращаем направление приземного ветра
- IF var_direction_increment IS NULL THEN
- RETURN par_ground_wind_direction;
- END IF;
- -- Рассчитываем среднее направление ветра
- RETURN par_ground_wind_direction + var_direction_increment;
- END;
- $$ LANGUAGE plpgsql;
- CREATE OR REPLACE FUNCTION calculate_wind_gun_corrections(
- IN par_height NUMERIC,
- IN par_temperature NUMERIC,
- IN par_pressure NUMERIC,
- IN par_wind_direction NUMERIC,
- IN par_wind_speed NUMERIC,
- IN par_bullet_demolition_range NUMERIC,
- OUT deviation_pressure NUMERIC,
- OUT deviation_temperature NUMERIC,
- OUT average_wind_speed NUMERIC,
- OUT average_wind_direction NUMERIC
- ) AS $$
- BEGIN
- -- Отклонение наземного давления
- deviation_pressure := public.fn_calc_header_pressure(par_pressure);
- -- Отклонение приземной виртуальной температуры
- deviation_temperature := public.fn_calc_header_temperature(par_temperature);
- -- Средняя скорость ветра
- average_wind_speed := calculate_average_wind_speed(par_height, par_bullet_demolition_range);
- -- Среднее направление ветра
- average_wind_direction := calculate_average_wind_direction(par_height, par_wind_direction);
- END;
- $$ LANGUAGE plpgsql;
- DO $$
- DECLARE
- -- Входные параметры
- var_height NUMERIC := 200; -- Высота (в метрах)
- var_temperature NUMERIC := 10; -- Температура (в градусах Цельсия)
- var_pressure NUMERIC := 740; -- Давление (в мм рт. ст.)
- var_wind_direction NUMERIC := 30; -- Направление приземного ветра (в градусах)
- var_wind_speed NUMERIC := 5; -- Скорость приземного ветра (в м/с)
- var_bullet_demolition_range NUMERIC := 80; -- Дальность сноса ветровых пуль (в метрах)
- -- Выходные параметры
- var_deviation_pressure NUMERIC; -- Отклонение наземного давления
- var_deviation_temperature NUMERIC; -- Отклонение приземной виртуальной температуры
- var_average_wind_speed NUMERIC; -- Средняя скорость ветра
- var_average_wind_direction NUMERIC; -- Среднее направление ветра
- BEGIN
- -- Вызов основной функции расчета
- SELECT * INTO var_deviation_pressure, var_deviation_temperature, var_average_wind_speed, var_average_wind_direction
- FROM calculate_wind_gun_corrections(
- var_height,
- var_temperature,
- var_pressure,
- var_wind_direction,
- var_wind_speed,
- var_bullet_demolition_range
- );
- -- Вывод результатов
- RAISE NOTICE '==============================';
- RAISE NOTICE 'Результаты расчета:';
- RAISE NOTICE 'Отклонение наземного давления: % мм рт. ст.', var_deviation_pressure;
- RAISE NOTICE 'Отклонение приземной виртуальной температуры: % °C', var_deviation_temperature;
- RAISE NOTICE 'Средняя скорость ветра: % м/с', var_average_wind_speed;
- RAISE NOTICE 'Среднее направление ветра: % градусов', var_average_wind_direction;
- RAISE NOTICE '==============================';
- END $$;
- -- Индексы для таблицы ranks
- CREATE INDEX idx_ranks_id ON public.ranks (id);
- -- Индексы для таблицы employees
- CREATE INDEX idx_employees_id ON public.employees (id);
- CREATE INDEX idx_employees_rank_id ON public.employees (rank_id);
- -- Индексы для таблицы measurment_types
- CREATE INDEX idx_measurment_types_id ON public.measurment_types (id);
- -- Индексы для таблицы measurment_input_params
- CREATE INDEX idx_measurment_input_params_id ON public.measurment_input_params (id);
- CREATE INDEX idx_measurment_input_params_measurment_type_id ON public.measurment_input_params (measurment_type_id);
- -- Индексы для таблицы measurment_baths
- CREATE INDEX idx_measurment_baths_id ON public.measurment_baths (id);
- CREATE INDEX idx_measurment_baths_user_id ON public.measurment_baths (user_id);
- CREATE INDEX idx_measurment_baths_measurment_input_param_id ON public.measurment_baths (measurment_input_param_id);
- -- Индексы для таблицы measurment_settings
- CREATE INDEX idx_measurment_settings_key ON public.measurment_settings (key);
- -- Индексы для таблицы calc_height_correction
- CREATE INDEX idx_calc_height_correction_id ON public.calc_height_correction (id);
- CREATE INDEX idx_calc_height_correction_measurment_type_id ON public.calc_height_correction (measurment_type_id);
- -- Индексы для таблицы calc_temperature_height_correction
- CREATE INDEX idx_calc_temperature_height_correction_id ON public.calc_temperature_height_correction (id);
- CREATE INDEX idx_calc_temperature_height_correction_calc_height_id ON public.calc_temperature_height_correction (calc_height_id);
- CREATE INDEX idx_calc_temperature_height_correction_calc_temperature_header_id ON public.calc_temperature_height_correction (calc_temperature_header_id);
- -- Индексы для таблицы calc_header_correction
- CREATE INDEX idx_calc_header_correction_id ON public.calc_header_correction (id);
- CREATE INDEX idx_calc_header_correction_measurment_type_id ON public.calc_header_correction (measurment_type_id);
- -- Индексы для таблицы speed_of_average_wind
- CREATE INDEX idx_speed_of_average_wind_height ON public.speed_of_average_wind (height);
- CREATE OR REPLACE VIEW effective_measurement_height AS
- WITH measurement_stats AS (
- -- CTE для подсчета общего количества измерений и количества ошибочных измерений
- SELECT
- e.id AS employee_id,
- e.name AS user_name,
- mr.description AS rank,
- COUNT(mb.id) AS total_measurements,
- SUM(CASE WHEN (public.fn_check_input_params(mip.height, mip.temperature, mip.pressure, mip.wind_direction, mip.wind_speed, mip.bullet_demolition_range)).is_check = False THEN 1 ELSE 0 END) AS error_count
- FROM
- public.employees e
- INNER JOIN
- public.ranks mr ON e.rank_id = mr.id
- INNER JOIN
- public.measurment_baths mb ON e.id = mb.user_id
- INNER JOIN
- public.measurment_input_params mip ON mb.measurment_input_param_id = mip.id
- GROUP BY
- e.id, e.name, mr.description
- )
- -- Основной запрос, использующий CTE
- SELECT
- ms.user_name AS "ФИО пользователя",
- ms.rank AS "Звание",
- MIN(mip.height) AS "Мин. высота метеопоста",
- MAX(mip.height) AS "Макс. высота метеопоста",
- ms.total_measurements AS "Всего измерений",
- ms.error_count AS "Из них ошибочны"
- FROM
- measurement_stats ms
- INNER JOIN
- public.measurment_baths mb ON ms.employee_id = mb.user_id
- INNER JOIN
- public.measurment_input_params mip ON mb.measurment_input_param_id = mip.id
- WHERE
- ms.total_measurements >= 5 AND ms.error_count < 10
- GROUP BY
- ms.user_name, ms.rank, ms.total_measurements, ms.error_count
- ORDER BY
- ms.error_count;
- CREATE OR REPLACE VIEW most_common_measurement_errors AS
- WITH log_data_text AS (
- -- Извлекаем данные из JSON-логов как текст
- SELECT
- cl.id AS log_id,
- cl.input_params->>'height' AS height_text,
- cl.input_params->>'temperature' AS temperature_text,
- cl.input_params->>'pressure' AS pressure_text,
- cl.input_params->>'wind_direction' AS wind_direction_text,
- cl.input_params->>'wind_speed' AS wind_speed_text,
- cl.input_params->>'bullet_demolition_range' AS bullet_demolition_range_text,
- cl.calculation_timestamp AS log_time
- FROM
- calculation_logs cl
- ),
- log_data AS (
- -- Конвертируем текстовые данные в numeric с обработкой null
- SELECT
- log_id,
- coalesce(height_text, '0')::numeric AS height,
- coalesce(temperature_text, '0')::numeric AS temperature,
- coalesce(pressure_text, '0')::numeric AS pressure,
- coalesce(wind_direction_text, '0')::numeric AS wind_direction,
- coalesce(wind_speed_text, '0')::numeric AS wind_speed,
- coalesce(bullet_demolition_range_text, '0')::numeric AS bullet_demolition_range,
- log_time
- FROM
- log_data_text
- ),
- error_data AS (
- -- Проверяем данные на ошибки
- SELECT
- ld.*,
- (public.fn_check_input_params(
- ld.height,
- ld.temperature,
- ld.pressure,
- ld.wind_direction,
- ld.wind_speed,
- ld.bullet_demolition_range
- )).error_message AS error_message
- FROM
- log_data ld
- WHERE
- (public.fn_check_input_params(
- ld.height,
- ld.temperature,
- ld.pressure,
- ld.wind_direction,
- ld.wind_speed,
- ld.bullet_demolition_range
- )).is_check = False
- ),
- error_counts AS (
- -- Группируем ошибки по типу и собираем пользователей
- SELECT
- ed.error_message,
- COUNT(*) AS error_count,
- STRING_AGG(DISTINCT e.name, ', ') AS users_list
- FROM
- error_data ed
- INNER JOIN
- measurment_baths mb ON ed.log_id = mb.measurment_input_param_id
- INNER JOIN
- employees e ON mb.user_id = e.id
- GROUP BY
- ed.error_message
- )
- -- Основной запрос, формирующий отчет
- SELECT
- error_message AS "Наименование ошибки",
- error_count AS "Количество ошибок",
- users_list AS "Список пользователей, которые допустили ошибку"
- FROM
- error_counts
- ORDER BY
- error_count DESC; (height_id, distance, degree)
- VALUES
- ((SELECT id FROM calc_height_correction WHERE height = 200), ARRAY[3,4,5,6,7,7,8,9,10,11,12,12], 0),
- ((SELECT id FROM calc_height_correction WHERE height = 400), ARRAY[4,5,6,7,8,9,10,11,12,13,14,15], 1),
- ((SELECT id FROM calc_height_correction WHERE height = 800), ARRAY[4,5,6,7,8,9,10,11,13,14,15,16], 2),
- ((SELECT id FROM calc_height_correction WHERE height = 1200), ARRAY[4,5,6,7,8,9,10,11,12,13,14,15,16], 2),
- ((SELECT id FROM calc_height_correction WHERE height = 1600), ARRAY[4,6,7,8,9,10,11,13,14,15,17,17], 3),
- ((SELECT id FROM calc_height_correction WHERE height = 2000), ARRAY[4,6,7,8,9,10,11,13,14,16,17,18], 3),
- ((SELECT id FROM calc_height_correction WHERE height = 2400), ARRAY[4,6,8,9,9,10,12,14,15,16,18,19], 3),
- ((SELECT id FROM calc_height_correction WHERE height = 3000), ARRAY[5,6,8,9,10,11,12,14,15,17,18,19], 4),
- ((SELECT id FROM calc_height_correction WHERE height = 4000), ARRAY[5,6,8,9,10,11,12,14,16,18,19,20], 4);
- CREATE OR REPLACE FUNCTION calc_avg_wind_speed(
- par_height NUMERIC,
- par_bullet_speed NUMERIC
- ) RETURNS NUMERIC AS $$
- DECLARE
- var_speed NUMERIC := 0;
- var_distance_index INT;
- var_distance_values NUMERIC[];
- BEGIN
- -- Если дальность сноса меньше 40 метров, скорость ветра равна 0
- IF par_bullet_speed < 40 THEN
- RETURN 0;
- END IF;
- -- Получаем данные из таблицы для заданной высоты
- SELECT distance
- INTO var_distance_values
- FROM speed_of_average_wind
- WHERE height = par_height;
- -- Если данные для высоты не найдены, возвращаем 0
- IF var_distance_values IS NULL THEN
- RETURN 0;
- END IF;
- -- Вычисляем индекс на основе дальности сноса
- var_distance_index := LEAST(GREATEST((par_bullet_speed - 40) / 10, 0), array_length(var_distance_values, 1) - 1);
- -- Получаем скорость ветра по индексу
- var_speed := var_distance_values[var_distance_index + 1]; -- Индексы в массиве начинаются с 1
- RETURN var_speed;
- END;
- $$ LANGUAGE plpgsql;
- CREATE OR REPLACE FUNCTION calc_avg_wind_dir(
- par_height NUMERIC,
- par_ground_wind_direction NUMERIC
- ) RETURNS NUMERIC AS $$
- DECLARE
- var_direction_increment NUMERIC;
- BEGIN
- -- Получаем приращение направления ветра из таблицы
- SELECT degree
- INTO var_direction_increment
- FROM speed_of_average_wind
- WHERE height = par_height;
- -- Если данные для высоты не найдены, возвращаем направление приземного ветра
- IF var_direction_increment IS NULL THEN
- RETURN par_ground_wind_direction;
- END IF;
- -- Рассчитываем среднее направление ветра
- RETURN par_ground_wind_direction + var_direction_increment;
- END;
- $$ LANGUAGE plpgsql;
- CREATE OR REPLACE FUNCTION calculate_wind_gun_corrections(
- IN par_height NUMERIC,
- IN par_temperature NUMERIC,
- IN par_pressure NUMERIC,
- IN par_wind_direction NUMERIC,
- IN par_wind_speed NUMERIC,
- IN par_bullet_speed NUMERIC,
- OUT deviation_pressure NUMERIC,
- OUT deviation_temperature NUMERIC,
- OUT average_wind_speed NUMERIC,
- OUT average_wind_direction NUMERIC
- ) AS $$
- BEGIN
- -- Отклонение наземного давления
- deviation_pressure := public.fn_calc_header_pressure(par_pressure);
- -- Отклонение приземной виртуальной температуры
- deviation_temperature := public.fn_calc_header_temperature(par_temperature);
- -- Средняя скорость ветра
- average_wind_speed := calc_avg_wind_speed(par_height, par_bullet_speed);
- -- Среднее направление ветра
- average_wind_direction := calc_avg_wind_dir(par_height, par_wind_direction);
- END;
- $$ LANGUAGE plpgsql;
- DO $$
- DECLARE
- -- Входные параметры
- var_height NUMERIC := 200; -- Высота (в метрах)
- var_temperature NUMERIC := 10; -- Температура (в градусах Цельсия)
- var_pressure NUMERIC := 740; -- Давление (в мм рт. ст.)
- var_wind_direction NUMERIC := 30; -- Направление приземного ветра (в градусах)
- var_wind_speed NUMERIC := 5; -- Скорость приземного ветра (в м/с)
- var_bullet_speed NUMERIC := 80; -- Дальность сноса ветровых пуль (в метрах)
- -- Выходные параметры
- var_deviation_pressure NUMERIC; -- Отклонение наземного давления
- var_deviation_temperature NUMERIC; -- Отклонение приземной виртуальной температуры
- var_average_wind_speed NUMERIC; -- Средняя скорость ветра
- var_average_wind_direction NUMERIC; -- Среднее направление ветра
- BEGIN
- -- Вызов основной функции расчета
- SELECT * INTO var_deviation_pressure, var_deviation_temperature, var_average_wind_speed, var_average_wind_direction
- FROM calculate_wind_gun_corrections(
- var_height,
- var_temperature,
- var_pressure,
- var_wind_direction,
- var_wind_speed,
- var_bullet_speed
- );
- -- Вывод результатов
- RAISE NOTICE '==============================';
- RAISE NOTICE 'Результаты расчета:';
- RAISE NOTICE 'Отклонение наземного давления: % мм рт. ст.', var_deviation_pressure;
- RAISE NOTICE 'Отклонение приземной виртуальной температуры: % °C', var_deviation_temperature;
- RAISE NOTICE 'Средняя скорость ветра: % м/с', var_average_wind_speed;
- RAISE NOTICE 'Среднее направление ветра: % градусов', var_average_wind_direction;
- RAISE NOTICE '==============================';
- END $$;
- -- Индексы для таблицы ranks
- CREATE INDEX idx_ranks_id ON public.ranks (id);
- -- Индексы для таблицы employees
- CREATE INDEX idx_employees_id ON public.employees (id);
- CREATE INDEX idx_employees_rank_id ON public.employees (rank_id);
- -- Индексы для таблицы measurment_types
- CREATE INDEX idx_measurment_types_id ON public.measurment_types (id);
- -- Индексы для таблицы measurement_params
- CREATE INDEX idx_measurement_params_id ON public.measurement_params (id);
- CREATE INDEX idx_measurement_params_measurment_type_id ON public.measurement_params (measurment_type_id);
- -- Индексы для таблицы measurement_batch
- CREATE INDEX idx_measurement_batch_id ON public.measurement_batch (id);
- CREATE INDEX idx_measurement_batch_user_id ON public.measurement_batch (user_id);
- CREATE INDEX idx_measurement_batch_measurement_param_id ON public.measurement_batch (measurement_param_id);
- -- Индексы для таблицы measurment_settings
- CREATE INDEX idx_measurment_settings_key ON public.measurment_settings (key);
- -- Индексы для таблицы calc_height_correction
- CREATE INDEX idx_calc_height_correction_id ON public.calc_height_correction (id);
- CREATE INDEX idx_calc_height_correction_measurment_type_id ON public.calc_height_correction (measurment_type_id);
- -- Индексы для таблицы calc_temperature_height_correction
- CREATE INDEX idx_calc_temperature_height_correction_id ON public.calc_temperature_height_correction (id);
- CREATE INDEX idx_calc_temperature_height_correction_calc_height_id ON public.calc_temperature_height_correction (calc_height_id);
- CREATE INDEX idx_calc_temperature_height_correction_calc_temperature_header_id ON public.calc_temperature_height_correction (calc_temperature_header_id);
- -- Индексы для таблицы calc_header_correction
- CREATE INDEX idx_calc_header_correction_id ON public.calc_header_correction (id);
- CREATE INDEX idx_calc_header_correction_measurment_type_id ON public.calc_header_correction (measurment_type_id);
- -- Индексы для таблицы speed_of_average_wind
- CREATE INDEX idx_speed_of_average_wind_height ON public.speed_of_average_wind (height);
- CREATE OR REPLACE VIEW effective_measurement_height AS
- WITH measurement_stats AS (
- -- CTE для подсчета общего количества измерений и количества ошибочных измерений
- SELECT
- e.id AS employee_id,
- e.name AS user_name,
- mr.description AS rank,
- COUNT(mb.id) AS total_measurements,
- SUM(CASE WHEN (public.fn_check_params(mip.height, mip.temperature, mip.pressure, mip.wind_direction, mip.wind_speed, mip.bullet_speed)).is_check = False THEN 1 ELSE 0 END) AS error_count
- FROM
- public.employees e
- INNER JOIN
- public.ranks mr ON e.rank_id = mr.id
- INNER JOIN
- public.measurement_batch mb ON e.id = mb.user_id
- INNER JOIN
- public.measurement_params mip ON mb.measurement_param_id = mip.id
- GROUP BY
- e.id, e.name, mr.description
- )
- -- Основной запрос, использующий CTE
- SELECT
- ms.user_name AS "ФИО пользователя",
- ms.rank AS "Звание",
- MIN(mip.height) AS "Мин. высота метеопоста",
- MAX(mip.height) AS "Макс. высота метеопоста",
- ms.total_measurements AS "Всего измерений",
- ms.error_count AS "Из них ошибочны"
- FROM
- measurement_stats ms
- INNER JOIN
- public.measurement_batch mb ON ms.employee_id = mb.user_id
- INNER JOIN
- public.measurement_params mip ON mb.measurement_param_id = mip.id
- WHERE
- ms.total_measurements >= 5 AND ms.error_count < 10
- GROUP BY
- ms.user_name, ms.rank, ms.total_measurements, ms.error_count
- ORDER BY
- ms.error_count;
- CREATE OR REPLACE VIEW most_common_measurement_errors AS
- WITH log_data_text AS (
- -- Извлекаем данные из JSON-логов как текст
- SELECT
- cl.id AS log_id,
- cl.params->>'height' AS height_text,
- cl.params->>'temperature' AS temperature_text,
- cl.params->>'pressure' AS pressure_text,
- cl.params->>'wind_direction' AS wind_direction_text,
- cl.params->>'wind_speed' AS wind_speed_text,
- cl.params->>'bullet_speed' AS bullet_speed_text,
- cl.calculation_timestamp AS log_time
- FROM
- calculation_logs cl
- ),
- log_data AS (
- -- Конвертируем текстовые данные в numeric с обработкой null
- SELECT
- log_id,
- coalesce(height_text, '0')::numeric AS height,
- coalesce(temperature_text, '0')::numeric AS temperature,
- coalesce(pressure_text, '0')::numeric AS pressure,
- coalesce(wind_direction_text, '0')::numeric AS wind_direction,
- coalesce(wind_speed_text, '0')::numeric AS wind_speed,
- coalesce(bullet_speed_text, '0')::numeric AS bullet_speed,
- log_time
- FROM
- log_data_text
- ),
- error_data AS (
- -- Проверяем данные на ошибки
- SELECT
- ld.*,
- (public.fn_check_params(
- ld.height,
- ld.temperature,
- ld.pressure,
- ld.wind_direction,
- ld.wind_speed,
- ld.bullet_speed
- )).error_message AS error_message
- FROM
- log_data ld
- WHERE
- (public.fn_check_params(
- ld.height,
- ld.temperature,
- ld.pressure,
- ld.wind_direction,
- ld.wind_speed,
- ld.bullet_speed
- )).is_check = False
- ),
- error_counts AS (
- -- Группируем ошибки по типу и собираем пользователей
- SELECT
- ed.error_message,
- COUNT(*) AS error_count,
- STRING_AGG(DISTINCT e.name, ', ') AS users_list
- FROM
- error_data ed
- INNER JOIN
- measurement_batch mb ON ed.log_id = mb.measurement_param_id
- INNER JOIN
- employees e ON mb.user_id = e.id
- GROUP BY
- ed.error_message
- )
- -- Основной запрос, формирующий отчет
- SELECT
- error_message AS "Наименование ошибки",
- error_count AS "Количество ошибок",
- users_list AS "Список пользователей, которые допустили ошибку"
- FROM
- error_counts
- ORDER BY
- error_count DESC;
|