> ## Documentation Index
> Fetch the complete documentation index at: https://docs.e6data.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Solve complete analysis problems

> Combine the earlier lessons to answer practical questions with small inputs.

TutorialApplies to: Unified engine deployments

Combine the earlier lessons to answer practical questions with small inputs.

## Before you start

You need Workbench and a running SQL engine. Every example includes its own input rows. No catalog, files, credentials, or external data is needed. These queries create no stored tables.

Copy the SQL into Workbench and run the statements in order. Compare the result with the table below the query. `WITH` names input data for one statement only. Each example can run on its own.

## 1. Build a sales report

What are order count and sales for each region?

```sql theme={"theme":{"light":"github-light","dark":"github-dark"}}
WITH orders(id, category, region, amount) AS (
  VALUES (1, 'Books', 'North', 20), (2, 'Games', 'South', 30),
         (3, 'Games', 'North', 15), (4, 'Books', 'North', 40),
         (5, 'Garden', 'South', 25), (6, 'Garden', 'North', 10)
)
SELECT region, COUNT(*) AS orders, SUM(amount) AS sales FROM orders GROUP BY region ORDER BY sales DESC, region;
```

**Expected result**

| region | orders | sales |
| - | - | - |
| North | 4 | 85 |
| South | 2 | 55 |

The report combines grouping, two measures, and result ordering.

**Change one thing:** Keep only amounts >= 25 before grouping. Expect South: 2 orders, 55 sales; North: 1 order, 40 sales.

## 2. Find repeat customers

Who placed more than one order?

```sql theme={"theme":{"light":"github-light","dark":"github-dark"}}
WITH customers(id, name) AS (VALUES (1, 'Ada'), (2, 'Ben'), (3, 'Cy')),
sales(order_id, customer_id, amount) AS (VALUES (10, 1, 20), (11, 1, 15), (12, 2, 30), (13, 9, 40))
SELECT c.name, COUNT(*) AS orders FROM customers c JOIN sales s ON c.id = s.customer_id GROUP BY c.name HAVING COUNT(*) > 1 ORDER BY c.name;
```

**Expected result**

| name | orders |
| - | - |
| Ada | 2 |

Join first, then count orders for each customer.

**Change one thing:** Use HAVING COUNT(\*) >= 1. Ben also appears with 1 order.

## 3. Find customers to contact

Who has never placed an order?

```sql theme={"theme":{"light":"github-light","dark":"github-dark"}}
WITH customers(id, name) AS (VALUES (1, 'Ada'), (2, 'Ben'), (3, 'Cy')),
sales(order_id, customer_id, amount) AS (VALUES (10, 1, 20), (11, 1, 15), (12, 2, 30), (13, 9, 40))
SELECT c.name FROM customers c WHERE NOT EXISTS (SELECT 1 FROM sales s WHERE s.customer_id = c.id) ORDER BY c.name;
```

**Expected result**

| name |
| - |
| Cy |

NOT EXISTS expresses the missing relationship directly.

**Change one thing:** Use EXISTS. Expect Ada and Ben.

## 4. Find the latest order status

What is the latest status of each order?

```sql theme={"theme":{"light":"github-light","dark":"github-dark"}}
WITH events(order_id, sequence, status) AS (VALUES (1, 1, 'New'), (1, 2, 'Paid'), (2, 1, 'New'), (2, 2, 'Cancelled'), (3, 1, 'New'), (3, 2, 'Shipped')),
ranked AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY order_id ORDER BY sequence DESC) AS position FROM events)
SELECT order_id, status FROM ranked WHERE position = 1 ORDER BY order_id;
```

**Expected result**

| order\_id | status |
| - | - |
| 1 | Paid |
| 2 | Cancelled |
| 3 | Shipped |

The event sequence defines recency. Rank first, then keep one row per order.

**Change one thing:** Use sequence ASC. All three statuses become New.

## 5. Find duplicate records

Which email appears more than once?

```sql theme={"theme":{"light":"github-light","dark":"github-dark"}}
WITH signups(id, email) AS (VALUES (1, 'ada@example.test'), (2, 'ben@example.test'), (3, 'ada@example.test'))
SELECT email, COUNT(*) AS copies FROM signups GROUP BY email HAVING COUNT(*) > 1 ORDER BY email;
```

**Expected result**

| email | copies |
| - | - |
| [ada@example.test](mailto:ada@example.test) | 2 |

Count by the business key to find repeated records.

**Change one thing:** Change the third email to [cy@example.test](mailto:cy@example.test). Expect no rows.

## 6. Compare actuals with targets

Which regions reached their target?

```sql theme={"theme":{"light":"github-light","dark":"github-dark"}}
WITH orders(id, category, region, amount) AS (
  VALUES (1, 'Books', 'North', 20), (2, 'Games', 'South', 30),
         (3, 'Games', 'North', 15), (4, 'Books', 'North', 40),
         (5, 'Garden', 'South', 25), (6, 'Garden', 'North', 10)
),
targets(region, target) AS (VALUES ('North', 80), ('South', 60)),
actuals AS (SELECT region, SUM(amount) AS sales FROM orders GROUP BY region)
SELECT a.region, a.sales, t.target, CASE WHEN a.sales >= t.target THEN 'Met' ELSE 'Below' END AS result FROM actuals a JOIN targets t ON a.region = t.region ORDER BY a.region;
```

**Expected result**

| region | sales | target | result |
| - | - | - | - |
| North | 85 | 80 | Met |
| South | 55 | 60 | Below |

Compute actuals separately, match targets, then classify each result.

**Change one thing:** Set the South target to 50. Both regions return Met.

## Continue

Continue to [Secrets](https://docs.e6data.com/transformation/learn/secrets.md), or return to [Learn Laminar](https://docs.e6data.com/transformation/learn.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.