diff --git a/calculate_largest_expensors.sql b/calculate_largest_expensors.sql index e69de29..7891c65 100644 --- a/calculate_largest_expensors.sql +++ b/calculate_largest_expensors.sql @@ -0,0 +1,39 @@ +USE memory.default; +-- We're preparing total expenses for employees +with expense_totals as ( + select + employee_id, + sum(unit_price * quantity) as total_expensed_amount + from + expense + group by + employee_id + having + sum(unit_price * quantity) > 1000 +), + +-- lookup for employee name +employee_lookup as ( + select + e.employee_id, + e.first_name || ' ' || e.last_name as employee_name, + e.manager_id, + m.first_name || ' ' || m.last_name as manager_name + from + employee e + left join employee m on e.manager_id = m.employee_id +) + +-- Final query combining both +select + et.employee_id, + el.employee_name, + el.manager_id, + el.manager_name, + et.total_expensed_amount +from + expense_totals et +join + employee_lookup el on et.employee_id = el.employee_id +order by + et.total_expensed_amount desc \ No newline at end of file diff --git a/create_employees.sql b/create_employees.sql index e69de29..031ffa5 100644 --- a/create_employees.sql +++ b/create_employees.sql @@ -0,0 +1,19 @@ +USE memory.default; + +CREATE TABLE employee ( + employee_id TINYINT, + first_name VARCHAR, + last_name VARCHAR, + job_title VARCHAR, + manager_id TINYINT +); + +INSERT INTO employee VALUES (1, 'Ian', 'James', 'CEO', 4); +INSERT INTO employee VALUES (2, 'Umberto', 'Torrielli', 'CSO', 1); +INSERT INTO employee VALUES (3, 'Alex', 'Jacobson', 'MD EMEA', 2); +INSERT INTO employee VALUES (4, 'Darren', 'Poynton', 'CFO', 2); +INSERT INTO employee VALUES (5, 'Tim', 'Beard', 'MD APAC', 2); +INSERT INTO employee VALUES (6, 'Gemma', 'Dodd', 'COS', 1); +INSERT INTO employee VALUES (7, 'Lisa', 'Platten', 'CHR', 6); +INSERT INTO employee VALUES (8, 'Stefano', 'Camisaca', 'GM Activation', 2); +INSERT INTO employee VALUES (9, 'Andrea', 'Ghibaudi', 'MD NAM', 2); \ No newline at end of file diff --git a/create_expenses.sql b/create_expenses.sql index e69de29..88d8110 100644 --- a/create_expenses.sql +++ b/create_expenses.sql @@ -0,0 +1,31 @@ +USE memory.default; + +--Let's first create table and inserts for the data, disregarding Items desciption as it is not needed moving forward + +CREATE TABLE if NOT EXISTS expense_employee_full_name ( + employee_name VARCHAR(100), + unit_price DECIMAL(8, 2), + quantity TINYINT +); + +INSERT INTO expense_employee_full_name (employee_name, unit_price, quantity) VALUES +('Alex Jacobson', 6.50, 14), +('Alex Jacobson', 11.00, 20), +('Alex Jacobson', 22.00, 18), +('Alex Jacobson', 13.00, 75), +('Andrea Ghibaudi', 300.00, 1), +('Darren Poynton', 40.00, 9), +('Umberto Torrielli', 17.50, 4); + + +CREATE TABLE if NOT EXISTS expense ( + employee_id TINYINT, + unit_price DECIMAL(8, 2), + quantity TINYINT +); + +-- Now we'll fill out expense table getting employee id's from employee table based on their fist and last name (assume here that employee first and last name are one word) +INSERT INTO expense +SELECT emp.employee_id, ex.unit_price, ex.quantity +FROM expense_employee_full_name ex +JOIN employee emp on emp.first_name = split(ex.employee_name, ' ')[1] and emp.last_name = split(ex.employee_name, ' ')[2] \ No newline at end of file diff --git a/create_invoices.sql b/create_invoices.sql index e69de29..b0ad9a3 100644 --- a/create_invoices.sql +++ b/create_invoices.sql @@ -0,0 +1,38 @@ +USE memory.default; + +create table if not exists supplier ( + supplier_id tinyint, + name varchar +); + + +create table if not exists invoice ( + supplier_id tinyint, + invoice_ammount decimal(8, 2), + due_date date +); + +create table if not exists invoice_raw ( + company_name varchar, + invoice_amount decimal(8, 2), + due_date varchar +); + +--Load the raw data +insert into invoice_raw (company_name, invoice_amount, due_date) values +('party animals', 6000, '3 months from now'), +('catering plus', 2000, '2 months from now'), +('catering plus', 1500, '3 months from now'), +('dave''s discos', 500, '1 month from now'), +('entertainment tonight', 6000, '3 months from now'), +('ice ice baby', 4000, '6 months from now'); + +--Translate company names to id's alphabetically and getting due date (based on the current date) +INSERT INTO invoice +SELECT + dense_rank() over (order by company_name asc) as num, + invoice_amount, + date_add('month', cast(split(due_date, ' ')[1] as integer), last_day_of_month(current_date)) as due_date +FROM + invoice_raw + diff --git a/find_manager_cycles.sql b/find_manager_cycles.sql index e69de29..0431f96 100644 --- a/find_manager_cycles.sql +++ b/find_manager_cycles.sql @@ -0,0 +1,19 @@ +USE memory.default; +-- Let's check paths employee -> their manager -> their manager -> ... +-- We stop when we encounter employee_id already present in the path +-- If the last employee_id is the same as the one we started with, it means we have a cycle + +WITH RECURSIVE cycle(employee_id, path) AS ( + SELECT employee_id, ARRAY[manager_id] + FROM employee + + UNION ALL + + SELECT c.employee_id, path || ARRAY[e.manager_id] + FROM cycle c + JOIN employee e ON c.path[cardinality(c.path)] = e.employee_id + WHERE NOT contains(c.path, e.manager_id) +) +SELECT * +FROM cycle +WHERE contains(path, employee_id); \ No newline at end of file diff --git a/generate_supplier_payment_plans.sql b/generate_supplier_payment_plans.sql index e69de29..3e487e6 100644 --- a/generate_supplier_payment_plans.sql +++ b/generate_supplier_payment_plans.sql @@ -0,0 +1,51 @@ +USE memory.default; +--first, we create a list of all payments - amount and date +--ten we aggregate by date of payment +--add the end window functions to get cumulative sum and amount left to be paid +WITH RECURSIVE installments(supplier_id, num_of_installments_left, payment, due_date) AS ( + SELECT + i.supplier_id, + date_diff('month', last_day_of_month(current_date), i.due_date) AS num_of_installments_left, + i.invoice_ammount / (date_diff('month', last_day_of_month(current_date), i.due_date) + 1), + last_day_of_month(current_date) AS due_date + FROM invoice i + + UNION ALL + + SELECT + supplier_id, + num_of_installments_left - 1, + payment, + due_date + interval '1' month + FROM installments + WHERE num_of_installments_left > 0 +) +SELECT + supplier_id, + supplier_name, + payment, + SUM(payment) OVER (PARTITION BY supplier_name) - + SUM(payment) OVER ( + PARTITION BY supplier_name + ORDER BY payment_date + ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ) AS balance_outstanding, + payment_date +FROM ( +SELECT + i.supplier_id, + s.supplier_name, + i.due_date as payment_date, + SUM(i.payment) AS payment +FROM installments i +JOIN ( + SELECT + RANK() OVER (ORDER BY company_name ASC) AS supplier_id, + company_name AS supplier_name + FROM ( + SELECT DISTINCT company_name FROM invoice_raw + ) +) s ON i.supplier_id = s.supplier_id +GROUP BY i.supplier_id, s.supplier_name, i.due_date +) payments +ORDER BY supplier_id, payment_date; \ No newline at end of file