diff --git a/Lab/Lab#5/lab5.sql b/Lab/Lab#5/lab5.sql index 5bf2073..5677732 100644 --- a/Lab/Lab#5/lab5.sql +++ b/Lab/Lab#5/lab5.sql @@ -1,6 +1,6 @@ SELECT * FROM bd_employees -WHERE last_name ~ '^[a-zA-Z]+-[a-zA-Z]+$'; +WHERE last_name ~ '^[a-zA-Z]+[-[a-zA-Z]]{0,}'; SELECT * FROM bd_employees @@ -18,19 +18,29 @@ SELECT last_name, FROM bd_employees; UPDATE staff -SET department = '60' -WHERE id = ( - SELECT manager_id - FROM employees - WHERE first_name LIKE 'Neena' AND last_name LIKE 'Kochhar'); +SET department = (SELECT department_name FROM departments WHERE department_id = 60) +WHERE department in ( + SELECT department_name + FROM departments + WHERE department_id in ( + SELECT department_id + FROM employees + WHERE manager_id = ( + SELECT employee_id + FROM employees + WHERE first_name = 'Neena' AND last_name= 'Kochhar'))); SELECT * FROM bd_employees WHERE LENGTH(REGEXP_REPLACE(first_name, '[^aeiouAEIOU]', '', 'g')) <= 3; -WITH tmp AS ( - SELECT chr(i+96), i FROM generate_series(1,26) i) -SELECT e.last_name sum(t.i) AS name_sum -FROM db_employees e -JOIN tmp t ON t.chr = ANY(string_to_array(LOWER(e.last_name), NULL)) -GROUP BY e.last_name; \ No newline at end of file +WITH tmp AS + ( + SELECT + last_name, + (REGEXP_MATCHES(LOWER(last_name), '[a-z]', 'g'))[1] AS l, + COUNT(*)*(ASCII((REGEXP_MATCHES(LOWER(last_name), '[a-z]', 'g'))[1]) - 96) AS cnt_l + FROM bd_employees + GROUP BY last_name, l + ) +SELECT last_name, sum(cnt_l) FROM tmp GROUP BY last_name; diff --git a/Lab/Lab#6/lab6.sql b/Lab/Lab#6/lab6.sql new file mode 100644 index 0000000..bd53776 --- /dev/null +++ b/Lab/Lab#6/lab6.sql @@ -0,0 +1,148 @@ +WITH RECURSIVE tmp AS ( + SELECT id, first_name, last_name, manager_id, 1 AS level + FROM bd6_employees + WHERE manager_id = 1 OR 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 department_names() AS $$ +DECLARE d_attrs RECORD; +BEGIN + +FOR d_attrs IN +WITH RECURSIVE tmp AS ( + SELECT + id, + first_name, + last_name, manager_id, + 1 AS level + FROM bd6_employees + WHERE manager_id = 1 or 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 LOOP RAISE INFO ' % % ', + +d_attrs.first_name, d_attrs.last_name; +END LOOP; +END $$ LANGUAGE plpgsql; +CALL department_names(); + +DECLARE + prev_employee NUMBER := 0; + mod_salary NUMBER; +BEGIN + FOR tmp IN ( + SELECT first_name, last_name, salary, + ROW_NUMBER() OVER (ORDER BY salary) AS salary_rank + FROM employees + ) + LOOP + IF emp.salary_rank = 1 THEN + modified_salary := FLOOR(emp.salary / 100) * 100; -- округляем до сотен в меньшую сторону + ELSE + modified_salary := FLOOR((emp.salary + previous_remainder) / 100) * 100; + previous_remainder := (emp.salary + previous_remainder) - modified_salary; + END IF; + + DBMS_OUTPUT.PUT_LINE('Фамилия: ' || emp.last_name || ', Имя: ' || emp.first_name || ', Модифицированная заработная плата: ' || modified_salary); + END LOOP; +END; + + +CREATE OR REPLACE PROCEDURE f() AS $$ +DECLARE d_attrs RECORD; +BEGIN + +FOR d_attrs IN + WITH RECURSIVE tmp AS ( + SELECT i AS f1, i2 AS f2, i3 AS f3,i4 AS f4,i5 AS f5 + FROM generate_series(1,200) i) + +SELECT * FROM tmp LOOP RAISE INFO ' % % % % %', + +d_attrs.f1, d_attrs.f2, d_attrs.f3, d_attrs.f4, d_attrs.f5; END LOOP; +END $$ LANGUAGE plpgsql; +CALL f(); + +WITH RECURSIVE tmp AS ( + SELECT id, first_name, last_name, manager_id, 1 AS level + FROM bd6_employees + WHERE manager_id = 1 OR 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 department_names() AS $$ +DECLARE d_attrs RECORD; +BEGIN + +FOR d_attrs IN +WITH RECURSIVE tmp AS ( + SELECT + id, + first_name, + last_name, manager_id, + 1 AS level + FROM bd6_employees + WHERE manager_id = 1 or 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 LOOP RAISE INFO ' % % ', + +d_attrs.first_name, d_attrs.last_name; +END LOOP; +END $$ LANGUAGE plpgsql; +CALL department_names(); + +CREATE OR REPLACE PROCEDURE modified_salary() AS $$ +DECLARE + prev_employee numeric := 0; + mod_salary numeric := ( + SELECT FLOOR(min(salary_in_euro) / 100) * 100 + FROM bd6_employees + ); + d_attrs RECORD; +BEGIN + FOR d_attrs IN WITH tmp AS ( + SELECT first_name, last_name, salary_in_euro + FROM bd6_employees + ORDER BY salary_in_euro ASC + ) + SELECT * FROM tmp + RAISE INFO ' % % % ', + d_attrs.last_name, + d_attrs.first_name, + mod_salary; + LOOP + mod_salary := FLOOR((d_attrs.salary_in_euro + prev_employee) / 100) * 100; + prev_employee := (d_attrs.salary_in_euro + prev_employee) - mod_salary; + RAISE INFO ' % % % ', + d_attrs.last_name, + d_attrs.first_name, + mod_salary; + END LOOP; +END $$ LANGUAGE plpgsql; +CALL modified_salary();