Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions calculate_largest_expensors.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
USE memory.default;

WITH EmployeeExpenses AS (
SELECT
employee_id,
SUM(unit_price * quantity) AS total_expensed_amount
FROM
memory.default.EXPENSE
GROUP BY
employee_id
HAVING
SUM(unit_price * quantity) > 1000
)
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,
ee.total_expensed_amount
FROM
memory.default.EMPLOYEE e
JOIN EmployeeExpenses ee ON e.employee_id = ee.employee_id
LEFT JOIN memory.default.EMPLOYEE m ON e.manager_id = m.employee_id
ORDER BY
ee.total_expensed_amount DESC;
24 changes: 24 additions & 0 deletions create_employees.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
USE memory.default;

-- DROP TABLE memory.default.EMPLOYEE;

CREATE TABLE memory.default.EMPLOYEE (
employee_id TINYINT,
first_name VARCHAR,
last_name VARCHAR,
job_title VARCHAR,
manager_id TINYINT
);

INSERT INTO memory.default.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);


19 changes: 19 additions & 0 deletions create_expenses.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
USE memory.default;

-- DROP TABLE memory.default.EXPENSE;

CREATE TABLE memory.default.EXPENSE (
employee_id TINYINT,
unit_price DECIMAL(8,2),
quantity TINYINT
);

INSERT INTO memory.default.EXPENSE VALUES
(3,6.50,14),
(3,11.0,22),
(3,22.0,18),
(3,13.00,75),
(9,300.00,1),
(4,40.00,9),
(2,17.50,4);

32 changes: 32 additions & 0 deletions create_invoices.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
USE memory.default;

-- DROP TABLE memory.default.INVOICE;

CREATE TABLE memory.default.INVOICE (
supplier_id TINYINT,
invoice_amount DECIMAL(8,2),
due_date DATE
);

-- DROP TABLE memory.default.SUPPLIER;


CREATE TABLE memory.default.SUPPLIER (
supplier_id TINYINT,
name VARCHAR
);

INSERT INTO memory.default.SUPPLIER (supplier_id, name) VALUES
(1, 'Catering Plus'),
(2, 'Dave''s Discos'),
(3, 'Entertainment tonight'),
(4, 'Ice Ice Baby'),
(5, 'Party Animals');

INSERT INTO memory.default.INVOICE (supplier_id, invoice_amount, due_date) VALUES
(1, 2000.00, DATE '2025-01-31'),
(1, 1500.00, DATE '2025-02-28'),
(2, 500.00, DATE '2024-12-31'),
(3, 6000.00, DATE '2025-02-28'),
(4, 4000.00, DATE '2025-04-30'),
(5, 6000.00, DATE '2025-02-28');
30 changes: 30 additions & 0 deletions find_manager_cycles.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
USE memory.default;

WITH RECURSIVE Hierarchy (employee_id, manager_id, path) AS (
SELECT
employee_id,
manager_id,
ARRAY[CAST(employee_id AS VARCHAR)] AS path
FROM
memory.default.EMPLOYEE

UNION ALL


SELECT
h.employee_id,
m.manager_id,
h.path || CAST(m.employee_id AS VARCHAR)
FROM
Hierarchy h
JOIN memory.default.EMPLOYEE m ON h.manager_id = m.employee_id
WHERE
NOT contains(h.path, CAST(m.employee_id AS VARCHAR))
)
SELECT
employee_id,
array_join(path, ' -> ') AS cycle
FROM
Hierarchy
WHERE
contains(path, CAST(manager_id AS VARCHAR));
52 changes: 52 additions & 0 deletions generate_supplier_payment_plans.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
USE memory.default;

-- STEPS I TOOK - thought process:
-- 1. Count the number of 'payments' (instalments) for each supplier.
-- 2. Divide all invoices into payments
-- 3. Aggregate payments per supplier for each month
-- 4. Set payment_date (last day of each consecutive month until payment month)
-- 5. Join with SUPPLIER table to get supplier names.
-- 6. Optimise code using CTE to improve readability and reusability

-- Get data about invoices
WITH invoice_data AS (
SELECT
supplier_id,
invoice_amount,
due_date,
date_diff('month', current_date, due_date) AS months_until_due,
current_date
FROM memory.default.INVOICE
), -- Generate payment schedule
payment_schedule AS (
SELECT
supplier_id,
invoice_amount / months_until_due AS monthly_payment,
last_day_of_month(date_add('month', month_index - 1, current_date)) AS payment_date
FROM invoice_data
CROSS JOIN UNNEST(sequence(1, months_until_due)) AS t(month_index)
), -- Aggregate monthly payments for each supplier
monthly_totals AS (
SELECT
supplier_id,
payment_date,
SUM(monthly_payment) AS total_monthly_payment,
SUM(SUM(monthly_payment)) OVER (PARTITION BY supplier_id) AS total_amount
FROM payment_schedule
GROUP BY supplier_id, payment_date
)

-- Generate balance_outstanding (left to pay after each payment) and join table SUPPLIERS to get supplier names
SELECT
monthly_totals.supplier_id,
suppliers.name AS supplier_name,
monthly_totals.total_monthly_payment AS payment_amount,
GREATEST(monthly_totals.total_amount - SUM(monthly_totals.total_monthly_payment) OVER (
PARTITION BY monthly_totals.supplier_id
ORDER BY monthly_totals.payment_date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
), 0) AS balance_outstanding,
monthly_totals.payment_date
FROM monthly_totals
JOIN memory.default.SUPPLIER AS suppliers ON monthly_totals.supplier_id = suppliers.supplier_id
ORDER BY monthly_totals.supplier_id, monthly_totals.payment_date;