mirror of
https://github.com/ada-dmitry/DB.mephi_ada.git
synced 2026-09-25 16:40:15 +00:00
reboot rep
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
DROP TABLE IF EXISTS bd6_departments;
|
||||
DROP TABLE IF EXISTS bd6_employees;
|
||||
|
||||
|
||||
CREATE TABLE bd6_departments(
|
||||
id integer PRIMARY KEY,
|
||||
name varchar(64),
|
||||
postal_code varchar(6),
|
||||
street varchar(64),
|
||||
building varchar(16),
|
||||
city varchar(32)
|
||||
);
|
||||
|
||||
INSERT INTO bd6_departments
|
||||
VALUES(10, 'Administration', '109658', 'Leningradskoe shosse', '1', 'Moscow'),
|
||||
(20, 'Marketing', '107701', 'Lenina', '22a', 'Volgograd'),
|
||||
(30, 'Purchasing', '109901', 'Mikluho-Maklaya', '8', 'Bryansk'),
|
||||
(40, 'Human Resources', '10967', '5-ya parkovaya', '16', 'Moscow'),
|
||||
(50, 'Shipping', '109659', '38 Bakinskih komissarov', '77', 'Moscow'),
|
||||
(60, 'IT', '109902', 'Pervomajskaya', '33', 'Kirov');
|
||||
|
||||
CREATE TABLE bd6_employees(
|
||||
id integer PRIMARY KEY,
|
||||
last_name varchar(64) NOT NULL,
|
||||
first_name varchar(64) NOT NULL,
|
||||
phone_number varchar(18),
|
||||
email varchar(32),
|
||||
department_id integer NOT NULL,
|
||||
manager_id integer,
|
||||
salary_in_euro numeric(8, 2) DEFAULT 0 NOT NULL,
|
||||
UNIQUE(last_name, first_name, department_id)
|
||||
);
|
||||
|
||||
|
||||
INSERT INTO bd6_employees VALUES(1, 'Radygin', 'Victor', '8-(495)-567-7788', 'vr@e.mail.mephi.ru', 10, NULL, 8000),
|
||||
(2, 'Kuprijanov', 'Dmitrij', '8-(495)-567-7794', 'kd@e.mail.mephi.ru', 60, 1, 6534.33),
|
||||
(3, 'Ivanov-Skladovskij', 'Ivan', '8-(495)-567-7799', 'ii1@mail.mephi.ru', 20, 1, 4404.14),
|
||||
(4, 'Petrov', 'Petr', '8-(495)-567-7794', 'petrovpetr@m.gmail.ru', 60, 2, 3456.43),
|
||||
(5, 'kozlov', 'Konstantin', '8-(495)-567-7794', 'kkozlov@mephi.ru', 60, 2, 2300),
|
||||
(6, 'Abramov', 'Abram', '8-(495)-567-7794', 'abramova@k75.mephi.ru', 60, 2, 2200.11),
|
||||
(7, 'IvanovпїЅ-SkladovskпїЅya-Petrova', 'Ivanka', '8-(495)-567-7794', 'ii2@mail.mephi.ru', 60, 4, 3756.33),
|
||||
(8, 'Petrov', 'Ivan', '8-(495)-567-7799', 'petrovivan@m.gmail.ru', 20, 3, 4850),
|
||||
(9, 'kozlov', 'Ivan', '8-(495)-567-7799', 'ikozlov@mephi.ru', 20, 3, 3460),
|
||||
(10, 'Abramov', 'Moisej', '8-(495)-567-7794', 'abramovm@k75.mephi.ru', 60, 4, 2345),
|
||||
(11, 'Petrov', 'Alex', '8-(495)-567-7799', 'petroval@m.gmail.ru', 20, 3, 2465),
|
||||
(12, 'kozlov', 'Maxim', '8-(495)-567-7799', 'mkozlov@mephi.ru', 20, 3, 2788),
|
||||
(13, 'Abramov', 'Isyaslav', '8-(495)-567-7738', 'abramovi@k75.mephi.ru', 30, 1, 6500);
|
||||
@@ -0,0 +1,163 @@
|
||||
DROP TABLE IF EXISTS bd6_employees;
|
||||
|
||||
CREATE TABLE bd6_departments(
|
||||
id integer PRIMARY KEY,
|
||||
name varchar(64),
|
||||
postal_code varchar(6),
|
||||
street varchar(64),
|
||||
building varchar(16),
|
||||
city varchar(32)
|
||||
);
|
||||
CREATE TABLE
|
||||
bd6_employees (
|
||||
id integer PRIMARY KEY,
|
||||
last_name varchar(64) NOT NULL,
|
||||
first_name varchar(64) NOT NULL,
|
||||
phone_number varchar(18),
|
||||
email varchar(32),
|
||||
department_id integer REFERENCES bd6_departments (id) NOT NULL,
|
||||
manager_id integer REFERENCES bd6_employees (id),
|
||||
salary_in_euro numeric(8, 2) DEFAULT 0 NOT NULL,
|
||||
UNIQUE (last_name, first_name, department_id)
|
||||
);
|
||||
|
||||
INSERT INTO bd6_departments
|
||||
VALUES(10, 'Administration', '109658', 'Leningradskoe shosse', '1', 'Moscow'),
|
||||
(20, 'Marketing', '107701', 'Lenina', '22a', 'Volgograd'),
|
||||
(30, 'Purchasing', '109901', 'Mikluho-Maklaya', '8', 'Bryansk'),
|
||||
(40, 'Human Resources', '10967', '5-ya parkovaya', '16', 'Moscow'),
|
||||
(50, 'Shipping', '109659', '38 Bakinskih komissarov', '77', 'Moscow'),
|
||||
(60, 'IT', '109902', 'Pervomajskaya', '33', 'Kirov');
|
||||
INSERT INTO
|
||||
bd6_employees
|
||||
VALUES
|
||||
(
|
||||
1,
|
||||
'Radygin',
|
||||
'Victor',
|
||||
'8-(495)-567-7788',
|
||||
'vr@e.mail.mephi.ru',
|
||||
10,
|
||||
NULL,
|
||||
8000
|
||||
),
|
||||
(
|
||||
2,
|
||||
'Kuprijanov',
|
||||
'Dmitrij',
|
||||
'8-(495)-567-7794',
|
||||
'kd@e.mail.mephi.ru',
|
||||
60,
|
||||
1,
|
||||
6534.33
|
||||
),
|
||||
(
|
||||
3,
|
||||
'Ivanov-Skladovskij',
|
||||
'Ivan',
|
||||
'8-(495)-567-7799',
|
||||
'ii1@mail.mephi.ru',
|
||||
20,
|
||||
1,
|
||||
4404.14
|
||||
),
|
||||
(
|
||||
4,
|
||||
'Petrov',
|
||||
'Petr',
|
||||
'8-(495)-567-7794',
|
||||
'petrovpetr@m.gmail.ru',
|
||||
60,
|
||||
2,
|
||||
3456.43
|
||||
),
|
||||
(
|
||||
5,
|
||||
'kozlov',
|
||||
'Konstantin',
|
||||
'8-(495)-567-7794',
|
||||
'kkozlov@mephi.ru',
|
||||
60,
|
||||
2,
|
||||
2300
|
||||
),
|
||||
(
|
||||
6,
|
||||
'Abramov',
|
||||
'Abram',
|
||||
'8-(495)-567-7794',
|
||||
'abramova@k75.mephi.ru',
|
||||
60,
|
||||
2,
|
||||
2200.11
|
||||
),
|
||||
(
|
||||
7,
|
||||
'IvanovпїЅ-SkladovskпїЅya-Petrova',
|
||||
'Ivanka',
|
||||
'8-(495)-567-7794',
|
||||
'ii2@mail.mephi.ru',
|
||||
60,
|
||||
4,
|
||||
3756.33
|
||||
),
|
||||
(
|
||||
8,
|
||||
'Petrov',
|
||||
'Ivan',
|
||||
'8-(495)-567-7799',
|
||||
'petrovivan@m.gmail.ru',
|
||||
20,
|
||||
3,
|
||||
4850
|
||||
),
|
||||
(
|
||||
9,
|
||||
'kozlov',
|
||||
'Ivan',
|
||||
'8-(495)-567-7799',
|
||||
'ikozlov@mephi.ru',
|
||||
20,
|
||||
3,
|
||||
3460
|
||||
),
|
||||
(
|
||||
10,
|
||||
'Abramov',
|
||||
'Moisej',
|
||||
'8-(495)-567-7794',
|
||||
'abramovm@k75.mephi.ru',
|
||||
60,
|
||||
4,
|
||||
2345
|
||||
),
|
||||
(
|
||||
11,
|
||||
'Petrov',
|
||||
'Alex',
|
||||
'8-(495)-567-7799',
|
||||
'petroval@m.gmail.ru',
|
||||
20,
|
||||
3,
|
||||
2465
|
||||
),
|
||||
(
|
||||
12,
|
||||
'kozlov',
|
||||
'Maxim',
|
||||
'8-(495)-567-7799',
|
||||
'mkozlov@mephi.ru',
|
||||
20,
|
||||
3,
|
||||
2788
|
||||
),
|
||||
(
|
||||
13,
|
||||
'Abramov',
|
||||
'Isyaslav',
|
||||
'8-(495)-567-7738',
|
||||
'abramovi@k75.mephi.ru',
|
||||
30,
|
||||
1,
|
||||
6500
|
||||
);
|
||||
@@ -0,0 +1,49 @@
|
||||
CREATE OR REPLACE PROCEDURE update_salary() AS $$
|
||||
DECLARE
|
||||
emp_record bd6_employees%ROWTYPE;
|
||||
counter integer := 0;
|
||||
min_salary bd6_employees.salary_in_euro%TYPE;
|
||||
max_salary bd6_employees.salary_in_euro%TYPE;
|
||||
BEGIN
|
||||
-- SELECT MIN(salary_in_euro), MAX(salary_in_euro) INTO min_salary, max_salary FROM bd6_employees;
|
||||
|
||||
FOR emp_record IN
|
||||
SELECT * FROM (SELECT * FROM bd6_employees ORDER BY salary_in_euro LIMIT 3) AS min_salaries
|
||||
LOOP
|
||||
DELETE FROM bd6_employees WHERE id = emp_record.id;
|
||||
counter := counter + 1;
|
||||
END LOOP;
|
||||
FOR emp_record IN
|
||||
SELECT * FROM (SELECT * FROM bd6_employees ORDER BY salary_in_euro DESC LIMIT 3) AS max_salaries
|
||||
LOOP
|
||||
UPDATE bd6_employees SET salary_in_euro = salary_in_euro + min_salary WHERE id = emp_record.id;
|
||||
counter := counter + 1;
|
||||
END LOOP;
|
||||
|
||||
RAISE NOTICE 'Successfully updated % bd6_employees.', counter;
|
||||
END $$ LANGUAGE plpgsql;
|
||||
CALL update_salary();
|
||||
|
||||
CREATE OR REPLACE PROCEDURE update_and_delete_salaries() AS $$
|
||||
BEGIN
|
||||
-- Увеличение заработной платы
|
||||
WITH lowest_salaries AS (
|
||||
SELECT id, salary_in_euro
|
||||
FROM bd6_employees
|
||||
ORDER BY salary_in_euro
|
||||
LIMIT 10
|
||||
), highest_salary AS (
|
||||
SELECT max(salary_in_euro) AS max_salary
|
||||
FROM bd6_employees
|
||||
)
|
||||
UPDATE bd6_employees e
|
||||
SET salary_in_euro = e.salary_in_euro + ls.salary_in_euro - (SELECT max_salary FROM highest_salary)
|
||||
FROM lowest_salaries ls
|
||||
WHERE e.id = ls.id;
|
||||
|
||||
-- Удаление сотрудников
|
||||
DELETE FROM bd6_employees WHERE id IN (SELECT id FROM lowest_salaries);
|
||||
|
||||
RAISE NOTICE 'Salaries updated and lowest paid bd6_employees deleted.';
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
@@ -0,0 +1,450 @@
|
||||
/* Вариант 1 || Работа 6 || Антипенко, Дробышевский */
|
||||
|
||||
|
||||
-- Task 1 --
|
||||
/* a) Напишите запрос, используя конструкцию WITH, выбирающий
|
||||
рекурсивно сотрудника с идентификатором 1 и все его подчинённых,
|
||||
как прямых, так и подчинённых более низкого ранга*.
|
||||
b) Напишите программу на языке PL/SQL, печатающую на экран фамилию
|
||||
и имя сотрудника с идентификатором 1 и всех его подчинённых, как
|
||||
прямых, так и подчинённых более низкого ранга. */
|
||||
|
||||
-- Пункт а)
|
||||
WITH RECURSIVE tmp AS (
|
||||
|
||||
SELECT id, first_name, last_name, manager_id, 1 AS level
|
||||
FROM bd6_employees
|
||||
WHERE id = 1
|
||||
UNION all
|
||||
SELECT e.id, e.first_name, e.last_name, e.manager_id, t.level + 1
|
||||
FROM bd6_employees e
|
||||
JOIN tmp t ON e.manager_id = t.id
|
||||
)
|
||||
SELECT *
|
||||
FROM tmp
|
||||
;
|
||||
|
||||
-- Пункт б)
|
||||
CREATE OR REPLACE PROCEDURE depa(integer) AS $$
|
||||
DECLARE
|
||||
d_attrs RECORD;
|
||||
i integer;
|
||||
l integer;
|
||||
BEGIN
|
||||
FOR d_attrs IN
|
||||
(
|
||||
SELECT id,last_name, first_name, manager_id
|
||||
FROM bd6_employees
|
||||
ORDER BY manager_id
|
||||
)
|
||||
LOOP
|
||||
IF d_attrs.manager_id=$1 THEN
|
||||
RAISE INFO ' % % % % ', d_attrs.first_name, d_attrs.last_name, d_attrs.id, d_attrs.manager_id;
|
||||
l:= d_attrs.id;
|
||||
CALL depa(l);
|
||||
END IF;
|
||||
END LOOP;
|
||||
END $$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE PROCEDURE dep(integer) AS $$
|
||||
DECLARE
|
||||
d_attrs RECORD;
|
||||
BEGIN
|
||||
FOR d_attrs IN
|
||||
(
|
||||
SELECT
|
||||
id,
|
||||
last_name,
|
||||
first_name,
|
||||
manager_id
|
||||
FROM bd6_employees
|
||||
ORDER BY manager_id
|
||||
)
|
||||
|
||||
LOOP
|
||||
IF d_attrs.id=$1 THEN
|
||||
RAISE INFO ' % % % % ', d_attrs.first_name, d_attrs.last_name, d_attrs.id, d_attrs.manager_id;
|
||||
END IF;
|
||||
END LOOP;
|
||||
CALL depa($1);
|
||||
END $$ LANGUAGE plpgsql;
|
||||
CALL dep(1);
|
||||
|
||||
-- Task 2 --
|
||||
/* Напишите программу на языке PL/SQL, выбирающую строки из таблицы
|
||||
employees в порядке возрастания заработной платы (salary) и печатающие на
|
||||
экран следующие данные: фамилия, имя, модифицированная заработная
|
||||
плата. Модифицированная заработная плата получается следующим
|
||||
образом: у первого по порядку сотрудника она округляется до сотен в
|
||||
меньшую сторону, а у всех последующих сотрудников она сначала
|
||||
увеличивается на остаток от округления, полученный от предыдущего
|
||||
сотрудника, а затем округляется до сотен в меньшую сторону. */
|
||||
|
||||
UPDATE bd6_employees SET salary_in_euro = 299 WHERE id = 3;
|
||||
|
||||
CREATE OR REPLACE PROCEDURE print_employees() AS $$
|
||||
DECLARE
|
||||
current_salary INTEGER;
|
||||
m_salary INTEGER;
|
||||
mod_salary INTEGER := 0;
|
||||
employee_rec RECORD;
|
||||
BEGIN
|
||||
FOR employee_rec IN
|
||||
(
|
||||
SELECT last_name, first_name, salary_in_euro
|
||||
FROM bd6_employees
|
||||
ORDER BY salary_in_euro
|
||||
)
|
||||
|
||||
LOOP
|
||||
current_salary := employee_rec.salary_in_euro;
|
||||
|
||||
m_salary := ((current_salary + mod_salary) / 100) * 100;
|
||||
|
||||
RAISE NOTICE 'Employee: % % || Modified Salary: %', employee_rec.last_name, employee_rec.first_name, m_salary;
|
||||
mod_salary := mod(current_salary + mod_salary,100);
|
||||
END LOOP;
|
||||
END $$ LANGUAGE plpgsql;
|
||||
|
||||
CALL print_employees();
|
||||
SELECT *
|
||||
FROM bd6_employees
|
||||
ORDER BY salary_in_euro;
|
||||
|
||||
|
||||
-- Task 3 --
|
||||
/* Напишите программу на языке PL/SQL, удаляющую 10 сотрудников с
|
||||
самой маленькой заработной платой. При этом их заработная плата должна
|
||||
добавиться 10 сотрудникам с самой большой заработной платой. Причём
|
||||
самая маленькая заработная плата должна добавиться к человеку с самой
|
||||
большой заработной платой. 2-я с конца заработная плата должна добавиться
|
||||
к человеку со второй по размеру заработной платой и т.д. */
|
||||
|
||||
CREATE OR REPLACE FUNCTION rearrange_salaries() RETURNS VOID AS $$
|
||||
DECLARE
|
||||
salaries RECORD;
|
||||
small NUMERIC[];
|
||||
larg NUMERIC[];
|
||||
const CONSTANT INTEGER = 3;
|
||||
BEGIN
|
||||
FOR salaries IN
|
||||
SELECT id, salary_in_euro
|
||||
FROM bd6_employees
|
||||
ORDER BY salary_in_euro
|
||||
LIMIT const
|
||||
LOOP
|
||||
small = array_append(small, (SELECT salary_in_euro FROM bd6_employees WHERE id = salaries.id));
|
||||
DELETE FROM bd6_employees
|
||||
WHERE id = salaries.id;
|
||||
END LOOP;
|
||||
|
||||
FOR salaries IN
|
||||
SELECT id, salary_in_euro
|
||||
FROM bd6_employees
|
||||
ORDER BY salary_in_euro DESC
|
||||
LIMIT const
|
||||
LOOP
|
||||
larg = array_append(larg, (SELECT id FROM bd6_employees WHERE id = salaries.id));
|
||||
END LOOP;
|
||||
|
||||
FOR i IN 1..const
|
||||
LOOP
|
||||
UPDATE bd6_employees
|
||||
SET salary_in_euro = salary_in_euro + small[i]
|
||||
WHERE id = larg[i];
|
||||
END LOOP;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
SELECT rearrange_salaries();
|
||||
|
||||
-- Task 4 --
|
||||
/* Создайте таблицу spiral с 5 полями f1, f2, f3, f4, f5 – целые числа.
|
||||
Напишите программу на языке PL/SQL, заполняющую данную таблицу 1000
|
||||
строк по следующему принципу:
|
||||
1 2 3 4 5
|
||||
10 9 8 7 6
|
||||
11 12 13 14 15
|
||||
20 19 18 17 16
|
||||
21 22 23 24 25 */
|
||||
|
||||
CREATE OR REPLACE PROCEDURE f() AS $$
|
||||
DECLARE d_attrs RECORD;
|
||||
BEGIN
|
||||
|
||||
FOR d_attrs IN WITH RECURSIVE tmp AS (
|
||||
SELECT 1+i*5 AS f1, 2+i*5 AS f2, 3+i*5 AS f3, 4+i*5 AS f4,5+i*5 AS f5
|
||||
FROM generate_series(0,199) i)
|
||||
|
||||
SELECT * FROM tmp
|
||||
LOOP
|
||||
case
|
||||
when ( mod(d_attrs.f1,2)!=0)
|
||||
then RAISE INFO ' % % % % %', d_attrs.f1, d_attrs.f2, d_attrs.f3, d_attrs.f4, d_attrs.f5;
|
||||
when ( mod(d_attrs.f1,2)=0)
|
||||
then RAISE INFO ' % % % % %', d_attrs.f5, d_attrs.f4, d_attrs.f3, d_attrs.f2, d_attrs.f1;
|
||||
end case;
|
||||
END LOOP;
|
||||
END $$ LANGUAGE plpgsql;
|
||||
call f();
|
||||
|
||||
-- Task 7 from lab4 --
|
||||
|
||||
|
||||
CREATE table staff(
|
||||
id integer primary key,
|
||||
name varchar(64) NOT NULL,
|
||||
department varchar(64) NOT NULL
|
||||
);
|
||||
|
||||
CREATE SEQUENCE staff_id_seq
|
||||
START WITH 12
|
||||
CYCLE
|
||||
INCREMENT BY 8
|
||||
CACHE 100;
|
||||
|
||||
|
||||
INSERT INTO staff VALUES
|
||||
(nextval('staff_id_seq'), 'Ivan Makarenko', 'Director');
|
||||
|
||||
INSERT INTO staff
|
||||
(SELECT nextval('staff_id_seq'), last_name, department_name
|
||||
FROM employees e JOIN departments d ON e.department_id = d.department_id);
|
||||
|
||||
UPDATE staff SET department = 'Innovations department'
|
||||
WHERE id < 40;
|
||||
|
||||
DELETE FROM staff
|
||||
WHERE name ILIKE('%K%');
|
||||
|
||||
CREATE VIEW dep_staff_counts AS
|
||||
SELECT department, COUNT(*) AS ecount
|
||||
FROM staff
|
||||
GROUP BY department;
|
||||
|
||||
SELECT * FROM dep_staff_counts;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- CREATE OR REPLACE PROCEDURE department_names(integer) AS $$
|
||||
-- DECLARE
|
||||
-- d_attrs RECORD;
|
||||
-- i INTEGER;
|
||||
-- l INTEGER;
|
||||
-- BEGIN
|
||||
-- FOR d_attrs IN
|
||||
-- (
|
||||
-- SELECT id,last_name, first_name, manager_id
|
||||
-- FROM bd6_employees order by manager_id
|
||||
-- )
|
||||
-- LOOP
|
||||
-- IF d_attrs.manager_id=$1 THEN
|
||||
-- RAISE INFO ' % % % % ', d_attrs.first_name, d_attrs.last_name, d_attrs.id, d_attrs.manager_id;
|
||||
-- l:= d_attrs.id;
|
||||
-- CALL department_names(l);
|
||||
-- END IF;
|
||||
-- END LOOP;
|
||||
-- END $$ LANGUAGE plpgsql;
|
||||
|
||||
|
||||
-- CREATE OR REPLACE PROCEDURE department_names2(integer) AS $$
|
||||
-- DECLARE d_attrs RECORD;
|
||||
-- BEGIN
|
||||
-- FOR d_attrs IN
|
||||
-- (
|
||||
-- SELECT id,last_name, first_name, manager_id
|
||||
-- FROM bd6_employees
|
||||
-- order by manager_id
|
||||
-- )
|
||||
|
||||
-- LOOP
|
||||
-- if d_attrs.id=$1 then
|
||||
-- RAISE INFO ' % % % % ', d_attrs.first_name, d_attrs.last_name, d_attrs.id, d_attrs.manager_id;
|
||||
-- end if;
|
||||
-- END LOOP;
|
||||
-- CALL department_names($1);
|
||||
-- END $$ LANGUAGE plpgsql;
|
||||
-- CALL department_names2(4);
|
||||
|
||||
|
||||
/* Вариант 1 || Работа 6 || Антипенко, Дробышевский */
|
||||
|
||||
|
||||
-- Task 1 --
|
||||
-- Пункт а)
|
||||
WITH RECURSIVE tmp AS (
|
||||
|
||||
SELECT id, first_name, last_name, manager_id, 1 AS level
|
||||
FROM bd6_employees
|
||||
WHERE id = 1
|
||||
UNION all
|
||||
SELECT e.id, e.first_name, e.last_name, e.manager_id, t.level + 1
|
||||
FROM bd6_employees e
|
||||
JOIN tmp t ON e.manager_id = t.id
|
||||
)
|
||||
SELECT *
|
||||
FROM tmp
|
||||
;
|
||||
|
||||
-- Пункт б)
|
||||
CREATE OR REPLACE PROCEDURE depa(integer) AS $$
|
||||
DECLARE
|
||||
d_attrs RECORD;
|
||||
i integer;
|
||||
l integer;
|
||||
BEGIN
|
||||
FOR d_attrs IN
|
||||
(
|
||||
SELECT id,last_name, first_name, manager_id
|
||||
FROM bd6_employees
|
||||
ORDER BY manager_id
|
||||
)
|
||||
LOOP
|
||||
IF d_attrs.manager_id=$1 THEN
|
||||
RAISE INFO ' % % % % ', d_attrs.first_name, d_attrs.last_name, d_attrs.id, d_attrs.manager_id;
|
||||
l:= d_attrs.id;
|
||||
CALL depa(l);
|
||||
END IF;
|
||||
END LOOP;
|
||||
END $$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE PROCEDURE dep(integer) AS $$
|
||||
DECLARE
|
||||
d_attrs RECORD;
|
||||
BEGIN
|
||||
FOR d_attrs IN
|
||||
(
|
||||
SELECT
|
||||
id,
|
||||
last_name,
|
||||
first_name,
|
||||
manager_id
|
||||
FROM bd6_employees
|
||||
ORDER BY manager_id
|
||||
)
|
||||
|
||||
LOOP
|
||||
IF d_attrs.id=$1 THEN
|
||||
RAISE INFO ' % % % % ', d_attrs.first_name, d_attrs.last_name, d_attrs.id, d_attrs.manager_id;
|
||||
END IF;
|
||||
END LOOP;
|
||||
CALL depa($1);
|
||||
END $$ LANGUAGE plpgsql;
|
||||
CALL dep(1);
|
||||
|
||||
-- Task 2 --
|
||||
|
||||
UPDATE bd6_employees SET salary_in_euro = 299 WHERE id = 3;
|
||||
|
||||
CREATE OR REPLACE PROCEDURE print_employees() AS $$
|
||||
DECLARE
|
||||
current_salary INTEGER;
|
||||
m_salary INTEGER;
|
||||
mod_salary INTEGER := 0;
|
||||
employee_rec RECORD;
|
||||
i INTEGER = 0;
|
||||
cnt INTEGER;
|
||||
BEGIN
|
||||
SELECT COUNT(*) INTO cnt FROM bd6_employees;
|
||||
FOR employee_rec IN
|
||||
(
|
||||
SELECT last_name, first_name, salary_in_euro
|
||||
FROM bd6_employees
|
||||
ORDER BY salary_in_euro
|
||||
)
|
||||
LOOP
|
||||
|
||||
current_salary := employee_rec.salary_in_euro;
|
||||
|
||||
IF cnt - 1 = i THEN
|
||||
m_salary := ((current_salary) / 100) * 100 + mod_salary;
|
||||
ELSE
|
||||
m_salary := ((current_salary) / 100) * 100;
|
||||
END IF;
|
||||
|
||||
RAISE NOTICE 'Employee: % % || Modified Salary: %', employee_rec.last_name, employee_rec.first_name, m_salary;
|
||||
|
||||
mod_salary := mod_salary + mod(current_salary, 100);
|
||||
i := i+1;
|
||||
|
||||
END LOOP;
|
||||
|
||||
END $$ LANGUAGE plpgsql;
|
||||
|
||||
CALL print_employees();
|
||||
SELECT *
|
||||
FROM bd6_employees
|
||||
ORDER BY salary_in_euro;
|
||||
|
||||
|
||||
-- Task 3 --
|
||||
CREATE OR REPLACE FUNCTION rearrange_salaries() RETURNS VOID AS $$
|
||||
DECLARE
|
||||
salaries RECORD;
|
||||
small NUMERIC[];
|
||||
larg NUMERIC[];
|
||||
const CONSTANT INTEGER = 10;
|
||||
BEGIN
|
||||
FOR salaries IN
|
||||
SELECT id, salary_in_euro
|
||||
FROM bd6_employees
|
||||
ORDER BY salary_in_euro
|
||||
LIMIT const
|
||||
LOOP
|
||||
small = array_append(small, (SELECT salary_in_euro FROM bd6_employees WHERE id = salaries.id));
|
||||
UPDATE bd6_employees SET manager_id = NULL WHERE manager_id = salaries.id;
|
||||
DELETE FROM bd6_employees
|
||||
WHERE id = salaries.id;
|
||||
END LOOP;
|
||||
|
||||
FOR salaries IN
|
||||
SELECT id, salary_in_euro
|
||||
FROM bd6_employees
|
||||
ORDER BY salary_in_euro DESC
|
||||
LIMIT const
|
||||
LOOP
|
||||
larg = array_append(larg, (SELECT id FROM bd6_employees WHERE id = salaries.id));
|
||||
END LOOP;
|
||||
|
||||
FOR i IN 1..const
|
||||
LOOP
|
||||
UPDATE bd6_employees
|
||||
SET salary_in_euro = salary_in_euro + small[i]
|
||||
WHERE id = larg[i];
|
||||
END LOOP;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
SELECT rearrange_salaries();
|
||||
|
||||
-- Task 4 --
|
||||
|
||||
CREATE OR REPLACE PROCEDURE f() AS $$
|
||||
DECLARE d_attrs RECORD;
|
||||
BEGIN
|
||||
|
||||
FOR d_attrs IN WITH RECURSIVE tmp AS (
|
||||
SELECT 1+i*5 AS f1, 2+i*5 AS f2, 3+i*5 AS f3, 4+i*5 AS f4,5+i*5 AS f5
|
||||
FROM generate_series(0,199) i)
|
||||
|
||||
SELECT * FROM tmp
|
||||
LOOP
|
||||
case
|
||||
when ( mod(d_attrs.f1,2)!=0)
|
||||
then RAISE INFO ' % % % % %', d_attrs.f1, d_attrs.f2, d_attrs.f3, d_attrs.f4, d_attrs.f5;
|
||||
when ( mod(d_attrs.f1,2)=0)
|
||||
then RAISE INFO ' % % % % %', d_attrs.f5, d_attrs.f4, d_attrs.f3, d_attrs.f2, d_attrs.f1;
|
||||
end case;
|
||||
END LOOP;
|
||||
END $$ LANGUAGE plpgsql;
|
||||
call f();
|
||||
|
||||
-- Task 7 from lab4 --
|
||||
DROP VIEW IF EXISTS dep_staff_counts;
|
||||
|
||||
CREATE VIEW dep_staff_counts AS
|
||||
SELECT department, COUNT(*) AS ecount
|
||||
FROM staff
|
||||
GROUP BY department;
|
||||
|
||||
SELECT * FROM dep_staff_counts;
|
||||
@@ -0,0 +1,72 @@
|
||||
CREATE OR REPLACE FUNCTION rearrange_salaries() RETURNS VOID AS $$
|
||||
DECLARE
|
||||
salaries RECORD;
|
||||
small NUMERIC[];
|
||||
larg NUMERIC[];
|
||||
const CONSTANT INTEGER = 10;
|
||||
BEGIN
|
||||
FOR salaries IN
|
||||
SELECT id, salary_in_euro
|
||||
FROM bd6_employees
|
||||
ORDER BY salary_in_euro
|
||||
LIMIT const
|
||||
LOOP
|
||||
small = array_append(small, (SELECT salary_in_euro FROM bd6_employees WHERE id = salaries.id));
|
||||
DELETE FROM bd6_employees
|
||||
WHERE id = salaries.id;
|
||||
END LOOP;
|
||||
|
||||
FOR salaries IN
|
||||
SELECT id, salary_in_euro
|
||||
FROM bd6_employees
|
||||
ORDER BY salary_in_euro DESC
|
||||
LIMIT const
|
||||
LOOP
|
||||
larg = array_append(larg, (SELECT id FROM bd6_employees WHERE id = salaries.id));
|
||||
END LOOP;
|
||||
|
||||
FOR i IN 1..const
|
||||
LOOP
|
||||
UPDATE bd6_employees
|
||||
SET salary_in_euro = salary_in_euro + small[i]
|
||||
WHERE id = larg[i];
|
||||
END LOOP;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
SELECT rearrange_salaries();
|
||||
|
||||
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION update_salaries() RETURNS VOID AS $$
|
||||
DECLARE
|
||||
max_salary_employee_id INTEGER;
|
||||
min_salaries numeric[];
|
||||
max_salaries numeric[];
|
||||
i INTEGER;
|
||||
const CONSTANT INTEGER = 10;
|
||||
BEGIN
|
||||
-- Получаем заработные платы последних 10 человек с самой маленькой заработной платой
|
||||
SELECT array_agg(id) FROM bd6_employees
|
||||
ORDER BY salary_in_euro ASC
|
||||
LIMIT const INTO min_salaries;
|
||||
|
||||
-- Получаем заработные платы 10 первых человек с самой большой заработной платой
|
||||
SELECT array_agg(id) FROM bd6_employees
|
||||
ORDER BY salary_in_euro DESC
|
||||
LIMIT const INTO max_salaries;
|
||||
|
||||
-- Добавляем заработные платы
|
||||
FOR i IN 1..const LOOP
|
||||
UPDATE bd6_employees
|
||||
SET salary_in_euro = salary_in_euro + min_salaries[i]
|
||||
WHERE id = max_salaries[i];
|
||||
END LOOP;
|
||||
|
||||
-- Удаляем 10 человек с наименьшей заработной платой
|
||||
DELETE FROM bd6_employees
|
||||
WHERE id IN (SELECT unnest(min_salaries));
|
||||
|
||||
RAISE NOTICE 'Заработные платы обновлены и % человек удалены', const;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
Reference in New Issue
Block a user