Browse Source

Homework 2

Vsevolod Levitan 2 months ago
parent
commit
ecda282efd
5 changed files with 77 additions and 19 deletions
  1. 11 16
      homework/1.sql
  2. 2 0
      homework/1.test.sql
  3. 59 0
      homework/2.sql
  4. 2 0
      homework/2.test.sql
  5. 3 3
      homework/init.sql

+ 11 - 16
homework/1.sql

@@ -2,21 +2,13 @@ DO $$
 begin
 
 -- Создаем таблицу званий
-if exists(select from pg_catalog.pg_tables where tablename = 'ranks') then
-raise notice 'Ranks table exists';
-else 
-create table ranks (id serial primary key, name varchar(32));
-end if;
+create table if not exists ranks (id serial primary key, name varchar(32));
 
 -- Создаем таблицу пользователей
-if exists(select from pg_catalog.pg_tables where tablename = 'users') then
-raise notice 'Users table exists';
-else
-create table users (id serial primary key, name varchar(64), rank_id integer references ranks(id));
-end if;
+create table if not exists users (id serial primary key, name varchar(64), rank_id integer references ranks(id));
 
 -- Заполняем звания
-if exists(select from ranks where name = 'Рядовой') then
+if exists(select from ranks where name = 'Рядовой' limit 1) then
 raise notice 'Ranks values exist';
 else
 insert into ranks(name) values ('Рядовой');
@@ -58,19 +50,22 @@ end if;
 
 -- Заполняем тестовые данные:
 -- -- Пользователь
-if exists(select from users) then
+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 $$;
+
+DO $$
+begin
+
 -- -- Измерение
-if exists(select from measurement_batch) then
+if (select count(id) from measurement_batch limit 1) > 0 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$$;
-
--- Проверяем
-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;

+ 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;

+ 59 - 0
homework/2.sql

@@ -0,0 +1,59 @@
+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;
+	
+	return interp;
+end;
+$func$;
+
+end $$;
+
+do $$
+begin
+create or replace function calc_adjustment(interp interpolation)
+	returns numeric
+	language plpgsql as $func$
+	declare adjustment numeric;
+begin
+	if interp.temperature_b = interp.temperature_t then
+		select 0 into adjustment;
+	elseif interp.temperature_b = interp.temperature or interp.temperature_t is null then
+		select interp.adjustment_b into adjustment;
+	elseif interp.temperature_t = interp.temperature or interp.temperature_b is null then
+		select intermp.adjustment_t 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 ('РУЖЬЕ');