diff --git a/calculate_largest_expensors.sql b/calculate_largest_expensors.sql index e69de29..9567d16 100644 --- a/calculate_largest_expensors.sql +++ b/calculate_largest_expensors.sql @@ -0,0 +1,22 @@ +USE memory.default; + +WITH ExpenseAccounts AS ( + SELECT + e.employee_id, + CONCAT(e.first_name, ' ', e.last_name) AS employee_name, + e.manager_id, + SUM(exp.unit_price * exp.quantity) AS total_expensed_amount + FROM EXPENSE exp + JOIN EMPLOYEE e ON exp.employee_id = e.employee_id + GROUP BY 1, 2, 3 + HAVING SUM(exp.unit_price * exp.quantity) > 1000 +) +SELECT + expa.employee_id, + expa.employee_name, + expa.manager_id, + CONCAT(m.first_name, ' ', m.last_name) AS manager_name, + expa.total_expensed_amount +FROM ExpenseAccounts expa +JOIN EMPLOYEE m ON expa.manager_id = m.employee_id +ORDER BY total_expensed_amount DESC; diff --git a/create_employees.sql b/create_employees.sql index e69de29..3e35272 100644 --- a/create_employees.sql +++ b/create_employees.sql @@ -0,0 +1,20 @@ +USE memory.default; + +CREATE TABLE EMPLOYEE ( + employee_id TINYINT, + first_name VARCHAR, + last_name VARCHAR, + job_title VARCHAR, + manager_id TINYINT +); + +INSERT INTO EMPLOYEE (employee_id, first_name, last_name, job_title, manager_id) VALUES +(1, 'Ian', 'James', 'CEO', 4), +(2, 'Umberto', 'Torrielli', 'CSO', 1), +(3, 'Alex', 'Jacobson', 'MD EMEA', 2), +(4, 'Darren', 'Poynton', 'CFO', 2), +(5, 'Tim', 'Beard', 'MD APAC', 2), +(6, 'Gemma', 'Dodd', 'COS', 1), +(7, 'Lisa', 'Platten', 'CHR', 6), +(8, 'Stefano', 'Camisaca', 'GM Activation', 2), +(9, 'Andrea', 'Ghibaudi', 'MD NAM', 2); \ No newline at end of file diff --git a/create_expenses.sql b/create_expenses.sql index e69de29..29ae230 100644 --- a/create_expenses.sql +++ b/create_expenses.sql @@ -0,0 +1,16 @@ +USE memory.default; + +CREATE TABLE expense( + employee_id TINYINT, + unit_price DECIMAL(8, 2), + quantity TINYINT +); + +INSERT INTO EXPENSE (employee_id, unit_price, quantity) VALUES +(3, 6.50, 14), -- Alex Jacobson - Drinks, lots of drinks +(3, 11.00, 20), -- Alex Jacobson - More Drinks +(3, 22.00, 18), -- Alex Jacobson - So Many Drinks! +(3, 13.00, 75), -- Alex Jacobson - I bought everyone in the bar a drink! +(9, 300.00, 1), -- Andrea Ghibaudi - Flights from Mexico back to New York +(4, 40.00, 9), -- Darren Poynton - Ubers to get us all home +(2, 17.50, 4); -- Umberto Torrielli - I had too much fun and needed something to eat \ No newline at end of file diff --git a/create_invoices.sql b/create_invoices.sql index e69de29..2b4f685 100644 --- a/create_invoices.sql +++ b/create_invoices.sql @@ -0,0 +1,27 @@ +USE memory.default; + +CREATE TABLE SUPPLIER ( + supplier_id TINYINT, + name VARCHAR +); + +CREATE TABLE INVOICE ( + supplier_id TINYINT, + invoice_amount DECIMAL(8, 2), + due_date DATE +); + +INSERT INTO SUPPLIER (supplier_id, name) VALUES +(1, 'Catering Plus'), +(2, 'Dave''s Discos'), +(3, 'Entertainment tonight'), +(4, 'Ice Ice Baby'), +(5, 'Party Animals'); + +INSERT INTO INVOICE (supplier_id, invoice_amount, due_date) VALUES +(5, 6000.00, last_day_of_month(CURRENT_DATE + INTERVAL '3' MONTH)), -- Party Animals +(1, 2000.00, last_day_of_month(CURRENT_DATE + INTERVAL '2' MONTH)), -- Catering Plus +(1, 1500.00, last_day_of_month(CURRENT_DATE + INTERVAL '3' MONTH)), -- Catering Plus +(2, 500.00, last_day_of_month(CURRENT_DATE + INTERVAL '1' MONTH)), -- Dave's Discos +(3, 6000.00, last_day_of_month(CURRENT_DATE + INTERVAL '3' MONTH)), -- Entertainment tonight +(4, 4000.00, last_day_of_month(CURRENT_DATE + INTERVAL '6' MONTH)); -- Ice Ice Baby \ No newline at end of file diff --git a/find_manager_cycles.sql b/find_manager_cycles.sql index e69de29..cde563f 100644 --- a/find_manager_cycles.sql +++ b/find_manager_cycles.sql @@ -0,0 +1,35 @@ +-- Find cycles in the manager-employee relationships +USE memory.default; + +WITH RECURSIVE EmployeeHierarchy(employee_id, manager_id, cycle_path) AS ( + SELECT + employee_id, + manager_id, + ARRAY[employee_id] AS cycle_path + FROM + EMPLOYEE + WHERE + employee_id IS NOT NULL + + UNION ALL + + SELECT + e.employee_id, + e.manager_id, + eh.cycle_path || e.employee_id -- Append the current employee_id to the cycle path + FROM + EMPLOYEE e + JOIN + EmployeeHierarchy eh ON e.manager_id = eh.employee_id + WHERE + array_position(eh.cycle_path, e.employee_id) = 0 -- Avoid cycles +) +SELECT + employee_id, + cycle_path +FROM + EmployeeHierarchy +WHERE + array_position(cycle_path, employee_id) > 0 AND cardinality(cycle_path) > 1 -- Only include entries where the employee is in the cycle, excluding single arrays +ORDER BY + employee_id; \ No newline at end of file diff --git a/generate_supplier_payment_plans.sql b/generate_supplier_payment_plans.sql index e69de29..cc29b9a 100644 --- a/generate_supplier_payment_plans.sql +++ b/generate_supplier_payment_plans.sql @@ -0,0 +1,60 @@ +-- Monthly payment plan for suppliers based on their invoices + +-- TODO: didn't have the time to rewrite the query to Trino SQL, but I would do it with cursor, so here is the pseudocode + +USE memory.default; + +DO $$ +DECLARE + r RECORD; + remaining_amount DECIMAL(8, 2); + payment_amount DECIMAL(8, 2); + payment_date DATE; + months_left TINYINT; +BEGIN + -- Calculate the payment amount and number of months for each supplier + FOR r IN ( + SELECT + s.supplier_id, + s.name AS supplier_name, + SUM(i.invoice_amount) AS total_invoice_amount, + MAX(i.due_date) AS max_due_date, + DATE_DIFF('month', CURRENT_DATE, MAX(i.due_date)) AS num_payments + FROM + SUPPLIER s + JOIN + INVOICE i ON s.supplier_id = i.supplier_id + WHERE + i.due_date > CURRENT_DATE + GROUP BY + s.supplier_id, s.name + HAVING + DATE_DIFF('month', CURRENT_DATE, MAX(i.due_date)) > 0 + ) LOOP + -- Set initial values for the cursor + remaining_amount := r.total_invoice_amount; + payment_amount := CEIL(remaining_amount / r.num_payments); + payment_date := last_day_of_month(CURRENT_DATE + INTERVAL '1' MONTH); + + -- Loop through the number of payments and output the payment details + FOR i IN 1..r.num_payments LOOP + -- Calculate the actual payment amount for the last payment if needed + IF remaining_amount < payment_amount THEN + payment_amount := remaining_amount; + END IF; + + -- Output the payment information + RAISE NOTICE 'Supplier ID: %, Supplier Name: %, Payment Amount: %, Balance Outstanding: %, Payment Date: %', + r.supplier_id, r.supplier_name, payment_amount, remaining_amount, payment_date; + + -- Decrease the remaining amount + remaining_amount := remaining_amount - payment_amount; + + -- Move to the next month + payment_date := last_day_of_month(payment_date + INTERVAL '1' MONTH); + END LOOP; + END LOOP; +END $$; + + +