Browse Source

Merge branch 'homework/2' of pivozavri/PostgresStudy2025 into master

Всеволод Левитан 2 months ago
parent
commit
d6c1cbb3fd
5 changed files with 150 additions and 34 deletions
  1. 76 31
      homework/1.sql
  2. 2 0
      homework/1.test.sql
  3. 67 0
      homework/2.sql
  4. 2 0
      homework/2.test.sql
  5. 3 3
      homework/init.sql

+ 76 - 31
homework/1.sql

@@ -1,51 +1,96 @@
 begin;
+DO $$ 
+begin
 
 -- Создаем таблицу званий
-create table ranks (id serial primary key, name varchar(32));
+create table if not exists ranks (id serial primary key, name varchar(32));
 
 -- Создаем таблицу пользователей
-create table users (id serial primary key, name varchar(64), rank_id integer);
-
--- Привязываем users(rank_id) -> ranks(id)
-alter table users add foreign key(rank_id) references ranks(id);
+create table if not exists users (id serial primary key, name varchar(64), rank_id integer references ranks(id));
 
 -- Заполняем звания
-insert into ranks(name) values ('Рядовой');
-insert into ranks(name) values ('Ефрейтор');
-insert into ranks(name) values ('Младший сержант');
-insert into ranks(name) values ('Сержант');
-insert into ranks(name) values ('Старший сержант');
-insert into ranks(name) values ('Старшина');
-insert into ranks(name) values ('Прапорщик');
-insert into ranks(name) values ('Старший прапорщик');
-insert into ranks(name) values ('Младший лейтенант');
-insert into ranks(name) values ('Лейтенант');
-insert into ranks(name) values ('Старший лейтенант');
-insert into ranks(name) values ('Капитан');
-insert into ranks(name) values ('Майор');
-insert into ranks(name) values ('Подполковник');
-insert into ranks(name) values ('Полковник');
+if exists(select from ranks limit 1) then
+	raise notice 'Ranks values exist';
+else
+	insert into ranks(name) values ('Рядовой');
+	insert into ranks(name) values ('Ефрейтор');
+	insert into ranks(name) values ('Младший сержант');
+	insert into ranks(name) values ('Сержант');
+	insert into ranks(name) values ('Старший сержант');
+	insert into ranks(name) values ('Старшина');
+	insert into ranks(name) values ('Прапорщик');
+	insert into ranks(name) values ('Старший прапорщик');
+	insert into ranks(name) values ('Младший лейтенант');
+	insert into ranks(name) values ('Лейтенант');
+	insert into ranks(name) values ('Старший лейтенант');
+	insert into ranks(name) values ('Капитан');
+	insert into ranks(name) values ('Майор');
+	insert into ranks(name) values ('Подполковник');
+	insert into ranks(name) values ('Полковник');
 insert into ranks(name) values ('Генерал майор');
-insert into ranks(name) values ('Генерал лейтенант');
-insert into ranks(name) values ('Генерал полковник');
-insert into ranks(name) values ('Генерал армии');
-insert into ranks(name) values ('Маршал России');
+	insert into ranks(name) values ('Генерал лейтенант');
+	insert into ranks(name) values ('Генерал полковник');
+	insert into ranks(name) values ('Генерал армии');
+	insert into ranks(name) values ('Маршал России');
+end if;
 
 -- Обновляем username(varchar) -> user_id(integer) в measurement_batch
-alter table measurement_batch rename column username to user_id;
-alter table measurement_batch alter column user_id type integer using null;
+if exists(select from information_schema.columns where table_name='measurement_batch' and column_name='user_id') then
+	raise notice 'user_id column already exists in table measurement_batch';
+else
+	alter table measurement_batch rename column username to user_id;
+	delete from measurement_params;
+	delete from measurement_batch;
+	alter table measurement_batch alter column user_id type integer using null;
+end if;
 
 -- Привязываем measurement_batch(user_id) -> users(id)
-alter table measurement_batch add foreign key(user_id) references users(id);
+if exists(select from information_schema.referential_constraints where constraint_name = 'measurement_batch_user_id_fkey') then
+	raise notice 'Foreign key measurement_batch(user_id) -> users(id) exists';
+else
+	alter table measurement_batch add foreign key(user_id) references users(id);
+end if;
 
 -- Заполняем тестовые данные:
 -- -- Пользователь
-insert into users(name, rank_id) values ('Левитан Всеволод Романович', (select id from ranks order by id desc limit 1));
+if exists(select from users limit 1) then
+	raise notice 'Test user exists';
+else
+	insert into users(name, rank_id) values ('Левитан Всеволод Романович', (select id from ranks order by id desc limit 1));
+end if;
+
+END $$;
+
+commit;
+
+begin;
+
+DO $$
+begin
+
 -- -- Измерение
-insert into measurement_batch(start_period, user_id, pos_x, pos_y) values (now(), (select id from users limit 1), 69.00, 42.00);
+if exists(select id from measurement_batch limit 1) then
+	raise notice 'Test batch exists';
+else
+	insert into measurement_batch(start_period, user_id, pos_x, pos_y) values (now(), (select id from users limit 1), 69.00, 42.00);
+end if;
+
+END$$;
 
 commit;
 
+begin;
+
+do $$
+begin
 
--- Проверяем
-select batch.id, batch.start_period, concat(rnk.name, ' ', usr.name), batch.pos_x, batch.pos_y from measurement_batch batch join users usr on batch.user_id = usr.id join ranks rnk on usr.rank_id = rnk.id;
+-- Данные измерения
+if exists(select id from measurement_params limit 1) then 
+	raise notice 'Test params exists';
+else
+	insert into measurement_params(measurement_type_id, measurement_batch_id, height, temperature, pressure, wind_speed, wind_direction, bullet_speed) values ((select id from measurement_types limit 1), (select id from measurement_batch limit 1), 100, 15, 750, 0, 0, 0);
+end if;
+
+end $$;
+
+commit;

+ 2 - 0
homework/1.test.sql

@@ -0,0 +1,2 @@
+-- Проверяем ДЗ №1
+select batch.id, batch.start_period, concat(rnk.name, ' ', usr.name) as user, batch.pos_x, batch.pos_y from measurement_batch batch join users usr on batch.user_id = usr.id join ranks rnk on usr.rank_id = rnk.id;

+ 67 - 0
homework/2.sql

@@ -0,0 +1,67 @@
+do $$
+begin
+create table if not exists temperature_adjustments
+(
+	id serial primary key,
+	temperature numeric,
+	adjustment numeric
+);
+if exists(select from temperature_adjustments limit 1) then
+raise notice 'Temperature_adjustments';
+else
+insert into temperature_adjustments(temperature, adjustment)
+values
+(0, 0), (5, 0.5), (10, 1), (15, 1), (20, 1.5), (25, 2), (30, 3.5), (40, 4.5);
+end if;
+
+if not exists(select from pg_type where typname = 'interpolation') then
+create type interpolation as (temperature_b numeric, temperature_t numeric, adjustment_b numeric, adjustment_t numeric, temperature numeric);
+end if;
+
+create or replace function calc_interpolation(temp1 numeric)
+	returns interpolation
+	language plpgsql as $func$
+	declare interp interpolation;
+begin
+	select temperature_b, temperature_t, adjustment_b, adjustment_t, temp1 as interpolation into interp from
+		(select temperature as temperature_b, adjustment as adjustment_b from temperature_adjustments where temperature <= temp1 order by temperature desc limit 1)
+	full join
+		(select temperature as temperature_t, adjustment as adjustment_t from temperature_adjustments where temperature >= temp1 order by temperature limit 1)
+	on true limit 1;
+
+	if interp.temperature_b is null or interp.temperature_t is null then raise exception ':c'; end if;
+	
+	return interp;
+end;
+$func$;
+
+end $$;
+
+do $$
+begin
+create or replace function calc_adjustment(interp interpolation)
+	returns numeric
+	language plpgsql as $func$
+	declare
+		adjustment numeric;
+		temp_min numeric;
+		temp_max numeric;
+begin
+	select min(temperature) from temperature_adjustments into temp_min;
+	select max(temperature) from temperature_adjustments into temp_max;
+	
+	if interp.temperature <= temp_min or interp.temperature_b = interp.temperature or interp.temperature_t is null then
+		select interp.adjustment_b into adjustment;
+	elseif interp.temperature >= temp_max or interp.temperature_t = interp.temperature or interp.temperature_b is null then
+		select interp.adjustment_t into adjustment;
+	elseif interp.temperature_b = interp.temperature_t then
+		select 0 into adjustment;
+	else 
+		select interp.adjustment_b+((interp.temperature - interp.temperature_b) / (interp.temperature_t - interp.temperature_b)) * (interp.adjustment_t - interp.adjustment_b)
+		into adjustment;
+	end if;
+	return adjustment;
+end;
+$func$;
+
+end $$;

+ 2 - 0
homework/2.test.sql

@@ -0,0 +1,2 @@
+-- Проверяем ДЗ №2
+select calc_adjustment(calc_interpolation(7));

+ 3 - 3
homework/init.sql

@@ -1,11 +1,11 @@
 begin;
 
 -- Создаем таблицу measurement_batch
-create table measurement_batch(id serial primary key, start_period timestamp, username varchar(64), pos_x numeric, pos_y numeric);
+create table if not exists measurement_batch(id serial primary key, start_period timestamp, username varchar(64), pos_x numeric, pos_y numeric);
 -- Создаем таблицу measurement_types
-create table measurement_types (id serial primary key, name varchar(64));
+create table if not exists measurement_types (id serial primary key, name varchar(64));
 -- Создаем таблицу measurement_params
-create table measurement_params(id serial primary key, measurement_type_id integer references measurement_types(id), measurement_batch_id integer references measurement_batch(id), height numeric, temperature numeric, pressure numeric, wind_speed numeric, wind_direction numeric, bullet_speed numeric);
+create table if not exists measurement_params(id serial primary key, measurement_type_id integer references measurement_types(id), measurement_batch_id integer references measurement_batch(id), height numeric, temperature numeric, pressure numeric, wind_speed numeric, wind_direction numeric, bullet_speed numeric);
 -- Добавляем тестовые типы измерений
 insert into measurement_types(name) values ('ДМК');
 insert into measurement_types(name) values ('РУЖЬЕ');