reboot rep

This commit is contained in:
ada-dmitry
2024-02-15 15:29:30 +03:00
parent 2360cb388f
commit 4623603411
25 changed files with 505 additions and 99 deletions
+174
View File
@@ -0,0 +1,174 @@
-- Лабораторная работа №7 || Антипенко, Дробышевский || Вариант 4 --
-- Задание 1
-- • Создайте две таблицы: people и people_log. Первая таблица должна
-- содержать поля идентификатор (id), имя (first_name), фамилия
-- (last_name), дата рождения (birthday), текущее состояние счёта
-- (amount). Поле id – это первичный ключ. Поле amount – это
-- действительное число. Вторая таблица должна содержать поля:
-- идентификатор человека (person_id) дата операции (operation_date),
-- сумма (sum). Поле person_id должно быть ограничено, как внешний
-- ключ, ссылающийся на поле id таблицы people. Поле operation_date
-- должно позволить сохранять дату и время. Поле sum – это
-- действительное число. Заполните таблицы people и people_log
-- несколькими записями (не менее 5 на таблицу).
CREATE TABLE people (
id SERIAL PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
birthday DATE,
amount DECIMAL(10, 2)
);
CREATE TABLE people_log (
id SERIAL PRIMARY KEY,
person_id INTEGER REFERENCES people(id),
operation_date TIMESTAMP,
sum DECIMAL(10, 2)
);
INSERT INTO people (first_name, last_name, birthday, amount)
VALUES
('Иван', 'Иванов', '1985-05-15', 1000.50),
('Петр', 'Петров', '1990-10-20', 750.25),
('Мария', 'Сидорова', '1978-12-03', 3000.75),
('Елена', 'Козлова', '1989-08-27', 200.00),
('Алексей', 'Смирнов', '1980-04-18', 1500.00);
INSERT INTO people_log (person_id, operation_date, sum)
VALUES
(1, '2023-09-20 10:15:00', 250.00),
(3, '2023-10-01 15:30:00', 800.50),
(2, '2023-11-05 08:45:00', 100.25),
(4, '2023-11-25 12:00:00', 50.00),
(5, '2023-12-02 18:20:00', 300.00);
SELECT * FROM people;
SELECT * FROM people_log;
-- Задание 2
-- • Напишите процедуру или функцию statement_of_acount, которая на
-- основе двух параметров: даты начала периода и даты окончания
-- периода печатала бы на экран данные (operation_date и sum) трёх самых
-- крупных операций с положительной суммой, трёх самых крупных
-- операций с отрицательной суммой и данные об общем числе операций
-- и среднем значении суммы.
CREATE OR REPLACE FUNCTION statement_of_account(start_date DATE, end_date DATE) RETURNS VOID AS $$
DECLARE
pos_counter INTEGER := 0;
neg_counter INTEGER := 0;
total_sum NUMERIC := 0;
total_count INTEGER := 0;
const CONSTANT INTEGER := 3;
avg_amount NUMERIC := 0;
operation RECORD;
BEGIN
FOR operation IN (
SELECT operation_date, sum
FROM people_log
WHERE operation_date BETWEEN start_date AND end_date
ORDER BY sum
) LOOP
IF operation.sum > 0 THEN
pos_counter := pos_counter + 1;
IF pos_counter <= const THEN
RAISE INFO 'Positive: %, Sum: %', operation.operation_date, operation.sum;
END IF;
ELSE
neg_counter := neg_counter + 1;
IF neg_counter <= const THEN
RAISE INFO 'Negative: %, Sum: %', operation.operation_date, operation.sum;
END IF;
END IF;
total_sum := total_sum + operation.sum;
total_count := total_count + 1;
END LOOP;
IF total_count > 0 THEN
avg_amount := total_sum / total_count;
END IF;
RAISE INFO 'Total number of operations: %', total_count;
RAISE INFO 'Average amount of transactions: %', avg_amount;
END
$$ LANGUAGE plpgsql;
-- Задание 3
-- • Напишите процедуру или функцию account_operation, которая на
-- основе двух параметров: идентификатора человека и суммы вносит
-- изменения в таблицы people и people_log. В таблице people у человека с
-- указанным в качестве параметра идентификатором состояние счёта
-- должно измениться на указанную в качестве параметра сумму. В
-- таблицу people_log должна быть добавлена запись с указанным в
-- качестве параметра идентификатором человека, текущей датой и
-- временем и указанной в качестве параметра суммой.
CREATE OR REPLACE PROCEDURE account_operation(new_id integer, add_sum numeric) AS $$
DECLARE
m integer;
BEGIN
select into m count(operation_date) from people_log where to_char(operation_date,'DD')= to_char(now(),'DD');
if m>=3 then
UPDATE people
SET amount = amount + add_sum
WHERE id = new_id;
INSERT INTO people_log (person_id, operation_date, sum) VALUES (new_id, CURRENT_TIMESTAMP(0), add_sum);
ELSE
raise info 'Too many operations'
END $$ LANGUAGE plpgsql;
CALL account_operation(5, 1000000);
SELECT * FROM people;
SELECT * FROM people_log;
CREATE OR REPLACE FUNCTION statement_of_account(start_date DATE, end_date DATE) RETURNS VOID AS $$
DECLARE
pos_counter INTEGER := 0;
neg_counter INTEGER := 0;
total_sum NUMERIC := 0;
total_count INTEGER := 0;
const CONSTANT INTEGER := 3;
avg_amount NUMERIC := 0;
operation RECORD;
BEGIN
FOR operation IN (
SELECT operation_date, sum
FROM people_log
WHERE operation_date BETWEEN start_date AND end_date
ORDER BY sum
) LOOP
IF operation.sum > 0 THEN
pos_counter := pos_counter + 1;
IF pos_counter <= const THEN
RAISE INFO 'Positive: %, Sum: %', operation.operation_date, operation.sum;
END IF;
ELSE
neg_counter := neg_counter + 1;
IF neg_counter <= const THEN
RAISE INFO 'Negative: %, Sum: %', operation.operation_date, operation.sum;
END IF;
END IF;
total_sum := total_sum + operation.sum;
total_count := total_count + 1;
END LOOP;
IF total_count > 0 THEN
avg_amount := total_sum / total_count;
END IF;
RAISE INFO 'Total number of operations: %', total_count;
RAISE INFO 'Average amount of transactions: %', avg_amount;
END
$$ LANGUAGE plpgsql;
+99
View File
@@ -0,0 +1,99 @@
DROP TABLE people_log IF EXISTS;
DROP TABLE people IF EXISTS;
--1--
CREATE TABLE people (
id SERIAL PRIMARY KEY,
first_name VARCHAR(64),
last_name VARCHAR(64),
birthday DATE,
amount NUMERIC(10,2)
);
CREATE TABLE people_log (
person_id INTEGER REFERENCES people(id),
operation_date TIMESTAMP,
sum NUMERIC(10,2)
);
INSERT INTO people (first_name, last_name, birthday, amount)
VALUES ('Andrey', 'Ad', '2004-03-09', 1000.00),
('Sanal', 'Bat', '2004-12-15', 2000.00),
('Alex', 'Yak', '2004-08-10', 3000.00),
('Dima', 'Klev', '2004-04-25', 4000.00),
('David', 'Dav', '2001-11-30', 5000.00),
('Reno', 'G', '2004-08-28', 6000.00),
('Ilya', 'Zim', '2005-01-06', 7000.00),
('Sema', 'Akh', '2005-12-01', 8000.00);
INSERT INTO people_log ( person_id, operation_date, sum)
VALUES
(1, '2022-01-05 17:15:00', 100.00),
(2, '2022-01-06 17:30:00', 300.00),
(3, '2022-01-07 17:45:00', 300.00),
(4, '2022-01-08 18:00:00', 400.00),
(5, '2022-01-09 18:15:00', 500.00),
(6, '2022-01-10 17:15:00', -100.00),
(7, '2022-01-12 17:15:00', -400.00),
(8, '2022-01-29 17:15:00', -200.00);
SELECT * FROM people;
SELECT * FROM people_log;
--2--
CREATE OR REPLACE PROCEDURE statement_of_acount(start_date DATE, end_date DATE) AS $$
DECLARE
pos_sum RECORD;
neg_sum RECORD;
total_count INTEGER;
avg_amount NUMERIC;
BEGIN
FOR pos_sum IN (
SELECT operation_date, sum
FROM people_log
WHERE operation_date BETWEEN start_date AND end_date AND sum > 0
ORDER BY sum DESC
LIMIT 3
) LOOP
RAISE INFO 'Положительная операция: %, Сумма: %', pos_sum.operation_date, pos_sum.sum;
END LOOP;
FOR neg_sum IN (
SELECT operation_date, sum
FROM people_log
WHERE operation_date BETWEEN start_date AND end_date AND sum < 0
ORDER BY sum ASC
LIMIT 3
) LOOP
RAISE INFO 'Отрицательная операция: %, Сумма: %', neg_sum.operation_date, neg_sum.sum;
END LOOP;
SELECT COUNT(*) INTO total_count
FROM people_log
WHERE operation_date BETWEEN start_date AND end_date;
SELECT AVG(sum) INTO avg_amount
FROM people_log
WHERE operation_date BETWEEN start_date AND end_date;
RAISE INFO 'Общее количество операций: %', total_count;
RAISE INFO 'Средняя сумма операций: %', avg_amount;
END $$ LANGUAGE plpgsql;
CALL statement_of_acount('2022-01-01', '2022-11-12');
--3--
CREATE OR REPLACE PROCEDURE account_operation(new_id integer, summa numeric) AS $$
DECLARE
BEGIN
UPDATE people SET amount = amount + summa WHERE id = new_id;
INSERT INTO people_log (person_id, operation_date, sum) VALUES (new_id, CURRENT_TIMESTAMP(0), summa);
END $$ LANGUAGE plpgsql;
CALL account_operation(1, 100);