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
33 changes: 33 additions & 0 deletions calculate_largest_expensors.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-- Query to report employees who expensed more than 1000
WITH EmployeeExpenses AS (
SELECT
e.employee_id,
CONCAT(e.first_name, ' ' , e.last_name) AS employee_name,
e.manager_id,
CONCAT(m.first_name, ' ' , m.last_name) AS manager_name,
SUM(ex.unit_price * ex.quantity) AS total_expensed_amount
FROM
EXPENSE ex
INNER JOIN
EMPLOYEE e
ON
ex.employee_id = e.employee_id
LEFT JOIN
EMPLOYEE m
ON
e.manager_id = m.employee_id
GROUP BY
e.employee_id, e.first_name, e.last_name, e.manager_id, m.first_name, m.last_name
)
SELECT
employee_id,
employee_name,
manager_id,
manager_name,
total_expensed_amount
FROM
EmployeeExpenses
WHERE
total_expensed_amount > 1000
ORDER BY
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;

-- Create EMPLOYEE table
CREATE TABLE IF NOT EXISTS EMPLOYEE (
employee_id TINYINT,
first_name VARCHAR,
last_name VARCHAR,
job_title VARCHAR,
manager_id TINYINT
);

-- Insert data into EMPLOYEE table
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);
31 changes: 31 additions & 0 deletions create_expenses.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
USE MEMORY.DEFAULT;

-- Create EXPENSE table using a CTE
CREATE TABLE IF NOT EXISTS EXPENSE AS
WITH EXPENSE_WITH_FULL_NAME (employee_full_name, unit_price, quantity) AS (
VALUES
('Alex Jacobson', 6.50, 14),
('Alex Jacobson', 11.00, 20),
('Alex Jacobson', 22.00, 18),
('Alex Jacobson', 13.00, 75),
('Andrea Ghibaudi', 40.00, 9),
('Andrea Ghibaudi', 17.50, 4)
),
EXPENSE_WITH_ID (employee_id, unit_price, quantity) AS (
SELECT
EMPLOYEE.employee_id,
CAST(TMP_EXPENSE.unit_price AS DECIMAL(8, 2)) AS unit_price,
CAST(TMP_EXPENSE.quantity AS TINYINT) AS quantity
FROM
EMPLOYEE
INNER JOIN
EXPENSE_WITH_FULL_NAME TMP_EXPENSE
ON
EMPLOYEE.first_name = SPLIT_PART(TMP_EXPENSE.employee_full_name, ' ', 1)
AND EMPLOYEE.last_name = SPLIT_PART(TMP_EXPENSE.employee_full_name, ' ', 2)
)
SELECT
CAST(employee_id AS INT) AS employee_id,
CAST(unit_price AS DECIMAL(8, 2)) AS unit_price,
CAST(quantity AS TINYINT) AS quantity
FROM EXPENSE_WITH_ID;
57 changes: 57 additions & 0 deletions create_invoices.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
USE MEMORY.DEFAULT;

-- Create SUPPLIER table
CREATE TABLE IF NOT EXISTS SUPPLIER AS (
WITH SUPPLIER_NAMES AS (
SELECT DISTINCT company_name
FROM (
VALUES
('Party Animals', 6000, 3),
('Catering Plus', 2000, 2),
('Catering Plus', 1500, 3),
('Dave''s Discos', 500, 1),
('Entertainment tonight', 6000, 3),
('Ice Ice Baby', 4000, 6)
) AS invoices_due(company_name, invoice_amount, due_date)
),
SUPPLIER_ASSIGNING_IDS_BY_ORDER AS (
SELECT
ROW_NUMBER() OVER (ORDER BY company_name) AS supplier_id,
company_name
FROM SUPPLIER_NAMES
)
SELECT
CAST(supplier_id AS TINYINT) AS supplier_id,
CAST(company_name AS VARCHAR) AS name
FROM SUPPLIER_ASSIGNING_IDS_BY_ORDER
);

-- Create INVOICE table
CREATE TABLE IF NOT EXISTS INVOICE AS (
WITH INVOICES_DUE (company_name, invoice_amount, invoice_date) AS (
VALUES
('Party Animals', 6000, 3),
('Catering Plus', 2000, 2),
('Catering Plus', 1500, 3),
('Dave''s Discos', 500, 1),
('Entertainment tonight', 6000, 3),
('Ice Ice Baby', 4000, 6)
),
INVOICE_WITH_SUPPLIER_IDS AS (
SELECT
S.supplier_id,
I.invoice_amount,
I.invoice_date
FROM
INVOICES_DUE I
INNER JOIN
SUPPLIER S
ON
I.company_name = S.name
)
SELECT
CAST(supplier_id AS TINYINT) AS supplier_id,
CAST(invoice_amount AS DECIMAL(8, 2)) AS invoice_amount,
LAST_DAY_OF_MONTH(DATE_ADD('MONTH', invoice_date, CURRENT_DATE)) AS due_date
FROM INVOICE_WITH_SUPPLIER_IDS
);
39 changes: 39 additions & 0 deletions find_manager_cycles.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
USE MEMORY.DEFAULT;

-- Recursive CTE to find employee-manager hierarchy loops
WITH RECURSIVE EmployeeHierarchy (employee_id, manager_id, path) AS (
-- Base case: Start with employees who have a manager
SELECT
employee_id,
manager_id,
ARRAY[CAST(employee_id AS VARCHAR)] AS path
FROM
EMPLOYEE
WHERE
manager_id IS NOT NULL

UNION ALL

-- Recursive case
SELECT
eh.employee_id,
e.manager_id,
eh.path || CAST(e.employee_id AS VARCHAR)
FROM
EmployeeHierarchy eh
INNER JOIN
EMPLOYEE e
ON
eh.manager_id = e.employee_id
WHERE
NOT CONTAINS(eh.path, CAST(e.employee_id AS VARCHAR))
)

-- Final output
SELECT
employee_id,
ARRAY_JOIN(path, ',') AS loop
FROM
EmployeeHierarchy
WHERE
manager_id = employee_id;
68 changes: 68 additions & 0 deletions generate_supplier_payment_plans.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
WITH SupplierInvoices AS (
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
FROM
SUPPLIER s
INNER JOIN
INVOICE i
ON
s.supplier_id = i.supplier_id
GROUP BY
s.supplier_id, s.name
),

-- Generate payment schedule for each supplier
PaymentSchedule AS (
SELECT
si.supplier_id,
si.supplier_name,
si.total_invoice_amount,
si.max_due_date,
-- Calculate the number of months until the due date
DATE_DIFF('MONTH', CURRENT_DATE, si.max_due_date) AS months_until_due,
-- Calculate the monthly payment amount (equal installments except the last one)
FLOOR(si.total_invoice_amount / DATE_DIFF('MONTH', CURRENT_DATE, si.max_due_date)) AS monthly_payment_amount,
-- Calculate the remaining amount for the last payment
si.total_invoice_amount - (FLOOR(si.total_invoice_amount / DATE_DIFF('MONTH', CURRENT_DATE, si.max_due_date)) * (DATE_DIFF('MONTH', CURRENT_DATE, si.max_due_date) - 1)) AS final_payment_amount
FROM
SupplierInvoices si
),

-- Generate payment dates and amounts
Payments AS (
SELECT
ps.supplier_id,
ps.supplier_name,
ps.total_invoice_amount,
-- Payment amount: equal installments except the last one
CASE
WHEN n.n < ps.months_until_due - 1 THEN ps.monthly_payment_amount
ELSE ps.final_payment_amount
END AS payment_amount,
-- Payment date: end of each month
LAST_DAY_OF_MONTH(DATE_ADD('MONTH', n.n, CURRENT_DATE)) AS payment_date,
-- Balance to pay: total invoice amount minus cumulative payments
ps.total_invoice_amount - SUM(CASE
WHEN n.n < ps.months_until_due - 1 THEN ps.monthly_payment_amount
ELSE ps.final_payment_amount
END) OVER (PARTITION BY ps.supplier_id ORDER BY n.n) AS balance_to_pay
FROM
PaymentSchedule ps
CROSS JOIN
UNNEST(SEQUENCE(0, ps.months_until_due - 1)) AS n(n)
)

-- Final output
SELECT
supplier_id,
supplier_name,
payment_amount,
balance_to_pay,
payment_date
FROM
Payments
ORDER BY
supplier_id, payment_date;