mirror of
https://github.com/ada-dmitry/DB.mephi_ada.git
synced 2026-09-24 08:00:16 +00:00
new files
This commit is contained in:
@@ -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;
|
||||
Reference in New Issue
Block a user