diff --git a/Lab/Lab#6/insert.sql b/Lab/Lab#6/insert.sql index a1cc812..a41dcfd 100644 --- a/Lab/Lab#6/insert.sql +++ b/Lab/Lab#6/insert.sql @@ -1,4 +1,4 @@ -DROP TABLE bd6_employees IF EXISTS; +DROP TABLE IF EXISTS bd6_employees; -- CREATE TABLE bd6_departments( -- id integer PRIMARY KEY, diff --git a/Lab/Lab#6/lab6.sql b/Lab/Lab#6/lab6.sql index e69de29..06a1c72 100644 --- a/Lab/Lab#6/lab6.sql +++ b/Lab/Lab#6/lab6.sql @@ -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; diff --git a/Lab/Lab#6/lab6_done.sql b/Lab/Lab#6/lab6_done.sql index af2a394..b79b71a 100644 --- a/Lab/Lab#6/lab6_done.sql +++ b/Lab/Lab#6/lab6_done.sql @@ -50,6 +50,7 @@ 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; @@ -74,32 +75,42 @@ CALL print_employees(); большой заработной платой. 2-я с конца заработная плата должна добавиться к человеку со второй по размеру заработной платой и т.д. */ -CREATE OR REPLACE PROCEDURE update_salary() AS $$ +CREATE OR REPLACE FUNCTION rearrange_salaries() RETURNS VOID 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; + salaries RECORD; + small NUMERIC[]; + larg NUMERIC[]; + const CONSTANT INTEGER = 10; 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 + 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; - 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(); + 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 – целые числа. diff --git a/Lab/Lab#6/test3.sql b/Lab/Lab#6/test3.sql index 35ed016..40cf955 100644 --- a/Lab/Lab#6/test3.sql +++ b/Lab/Lab#6/test3.sql @@ -1,26 +1,36 @@ -CREATE OR REPLACE PROCEDURE update_salary() AS $$ +CREATE OR REPLACE FUNCTION rearrange_salaries() RETURNS VOID 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; + salaries RECORD; + small NUMERIC[]; + larg NUMERIC[]; + const CONSTANT INTEGER = 10; 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 + 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; - 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(); \ No newline at end of file + 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(); \ No newline at end of file diff --git a/Practice/27_11.sql b/Practice/27_11.sql new file mode 100644 index 0000000..6634436 --- /dev/null +++ b/Practice/27_11.sql @@ -0,0 +1,104 @@ +-- Task 1 -- + +CREATE OR REPLACE PROCEDURE molodec() AS $$ +DECLARE + name1 varchar := 'Julia'; + name2 varchar := 'Пустотааа'; +BEGIN + RAISE INFO ' %, %, вы молодцы! ', name1, name2; + +END $$ LANGUAGE plpgsql; +CALL molodec(); + +-- Task 2 -- + +CREATE OR REPLACE PROCEDURE fiiiizika() AS $$ +DECLARE + velocity_kmh NUMERIC := 60; + time_seconds NUMERIC := 30; + velocity_ms NUMERIC; + distance_m NUMERIC; + train_length_m NUMERIC; +BEGIN + + velocity_ms := velocity_kmh * 1000 / 3600; + + distance_m := velocity_ms * time_seconds; + train_length_m := distance_m; + + RAISE INFO ' % ', TRUNC(train_length_m); +END; +$$ LANGUAGE plpgsql; +CALL fiiiizika(); + + + +-- Task 3 -- + +CREATE OR REPLACE PROCEDURE show_city_streets() AS $$ +DECLARE + city_record RECORD; +BEGIN + FOR city_record IN SELECT city, street_address FROM locations + LOOP + RAISE NOTICE 'В городе % есть улица %', + city_record.city, city_record.street_address; + END LOOP; +END; +$$ LANGUAGE plpgsql; + +CALL show_city_streets(); + + +-- Task 4 -- + +CREATE OR REPLACE PROCEDURE factorial(n INTEGER) AS $$ +DECLARE + result INTEGER := 1; + i INTEGER := 1; +BEGIN + WHILE i <= n LOOP + result := result * i; + i := i + 1; + END LOOP; + RAISE INFO ' % ', result; +END; +$$ LANGUAGE plpgsql; + +CALL factorial(10); + +-- Task 5 -- + +CREATE OR REPLACE FUNCTION get_employees_and_managers_names() +RETURNS TABLE (employee_name TEXT, manager_name TEXT) AS $$ +BEGIN + RETURN QUERY + SELECT e.first_name || ' ' || e.last_name AS employee_name, + COALESCE(m.first_name || ' ' || m.last_name, 'No manager') AS manager_name + FROM employees e + LEFT JOIN employees m ON e.manager_id = m.employee_id; +END; +$$ LANGUAGE plpgsql; + +SELECT get_employees_and_managers_names(); + +-- Task 6 -- + +CREATE OR REPLACE FUNCTION binary_to_decimal(binary_num VARCHAR) +RETURNS NUMERIC AS $$ +DECLARE + decimal_num NUMERIC := 0; + power NUMERIC := 0; + bit NUMERIC; +BEGIN + FOR i IN REVERSE 1..LENGTH(binary_num) LOOP + bit := CAST(SUBSTRING(binary_num FROM i FOR 1) AS NUMERIC); + decimal_num := decimal_num + (bit * (2 ^ power)); + power := power + 1; + END LOOP; + RETURN decimal_num; +END; +$$ LANGUAGE plpgsql; + +SELECT binary_to_decimal('101'); +