Skip to content

Commit

Permalink
Merge pull request #32
Browse files Browse the repository at this point in the history
Add more questions
  • Loading branch information
Bilbottom authored Jul 6, 2024
2 parents 455a8ff + bfc41b4 commit 195640d
Show file tree
Hide file tree
Showing 16 changed files with 690 additions and 35 deletions.
24 changes: 13 additions & 11 deletions docs/challenging-sql-problems/challenging-sql-problems.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,24 @@ As long as you know your database features and query patterns, these are fairly

These require a bit more thinking.

1. [Funnel analytics](problems/silver/funnel-analytics.md)
2. [Bannable login activity](problems/silver/bannable-login-activity.md)
3. [Bus routes](problems/silver/bus-routes.md)
4. [Decoding datelist ints](problems/silver/decoding-datelist-ints.md)
5. [Region precipitation](problems/silver/region-precipitation.md)
6. [Predicting values](problems/silver/predicting-values.md)
7. [Mandelbrot set](problems/silver/mandelbrot-set.md)
8. [Customer sales running totals](problems/silver/customer-sales-running-totals.md)
1. [Metric correlation](problems/silver/metric-correlation.md)
2. [Funnel analytics](problems/silver/funnel-analytics.md)
3. [Bannable login activity](problems/silver/bannable-login-activity.md)
4. [Bus routes](problems/silver/bus-routes.md)
5. [Decoding datelist ints](problems/silver/decoding-datelist-ints.md)
6. [Region precipitation](problems/silver/region-precipitation.md)
7. [Predicting values](problems/silver/predicting-values.md)
8. [Mandelbrot set](problems/silver/mandelbrot-set.md)
9. [Customer sales running totals](problems/silver/customer-sales-running-totals.md)

### 🟡 Gold Tier

Expect to spend a bit of time on these.

1. [Encoding datelist ints](problems/gold/encoding-datelist-ints.md)
2. [Loan repayment schedules](problems/gold/loan-repayment-schedule.md)
3. [Travel plans](problems/gold/travel-plans.md)
1. [Loan repayment schedules](problems/gold/loan-repayment-schedule.md)
2. [Supply chain network](problems/gold/supply-chain-network.md)
3. [Encoding datelist ints](problems/gold/encoding-datelist-ints.md)
4. [Travel plans](problems/gold/travel-plans.md)

---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,22 +84,7 @@ A worked example is provided below to help illustrate the encoding.

### Worked example

To help illustrate the encoding, consider the following events:

| event_id | user_id | event_datetime | event_type |
| -------: | ------: | :------------------ | :--------- |
| 1 | 1 | 2024-01-01 01:03:00 | login |
| 2 | 1 | 2024-01-04 01:02:00 | login |
| 3 | 1 | 2024-01-05 01:01:00 | login |
| 4 | 1 | 2024-01-06 01:00:00 | logout |
| 5 | 1 | 2024-01-07 01:05:00 | logout |
| 6 | 1 | 2024-01-07 01:06:00 | logout |
| 7 | 2 | 2024-01-08 01:07:00 | login |
| 8 | 2 | 2024-01-09 01:08:00 | login |
| 9 | 2 | 2024-01-10 01:09:00 | login |
| 10 | 2 | 2024-01-10 01:10:00 | logout |
| 11 | 2 | 2024-01-11 01:11:00 | logout |
| 12 | 2 | 2024-01-12 01:12:00 | logout |
To help illustrate the encoding, consider the following events in the **Sample input**.

We'll walk through each of the events and how they contribute to different sessions.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,7 @@ A worked example is provided below to help illustrate the loan calculations.

### Worked example

To help illustrate the loan calculations, consider the following loan:

- `loan_value`: 10,000.00
- `interest_rate`: 0.01
- `repayments`: 6
- `start_date`: 2024-01-01
To help illustrate the loan calculations, consider the loan in the **Sample input**.

A loan with these details will have a monthly repayment value of 1,725.48 (rounded to 2 decimal places).

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
```sql
with
locations(location_id, location_type) as (
values
(1, 'supplier'),
(2, 'supplier'),
(3, 'depot'),
(4, 'depot'),
(5, 'store')
),
deliveries(delivery_date, from_location_id, to_location_id, product_id, quantity) as (
values
('2024-01-01 01:23:53'::timestamp, 1, 3, 123, 25),
('2024-01-01 06:27:54'::timestamp, 2, 4, 123, 25),
('2024-01-01 12:27:39'::timestamp, 4, 5, 123, 25),
('2024-01-01 17:12:59'::timestamp, 1, 3, 123, 30),
('2024-01-02 01:27:57'::timestamp, 3, 5, 123, 25),
('2024-01-02 05:16:08'::timestamp, 3, 4, 123, 30),
('2024-01-02 05:40:53'::timestamp, 2, 3, 123, 20),
('2024-01-02 07:29:53'::timestamp, 1, 4, 123, 30),
('2024-01-02 09:22:53'::timestamp, 3, 5, 123, 20),
('2024-01-02 18:28:39'::timestamp, 4, 5, 123, 60)
),
sales(sale_datetime, store_id, product_id, quantity) as (
values
('2024-01-01 14:56:12'::timestamp, 5, 123, 5),
('2024-01-01 16:28:24'::timestamp, 5, 123, 3),
('2024-01-01 16:35:38'::timestamp, 5, 123, 4),
('2024-01-01 20:13:46'::timestamp, 5, 123, 2),
('2024-01-02 09:37:11'::timestamp, 5, 123, 12),
('2024-01-02 14:02:57'::timestamp, 5, 123, 30),
('2024-01-02 14:21:39'::timestamp, 5, 123, 3),
('2024-01-02 16:44:26'::timestamp, 5, 123, 8),
('2024-01-02 18:28:37'::timestamp, 5, 123, 2)
)
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
```sql
solution(stock_date, store_id, supplier_id, stock_volume, stock_proportion) as (
values
('2024-01-01'::date, 5, 1, 0, 0.00),
('2024-01-01'::date, 5, 2, 11, 100.00),
('2024-01-02'::date, 5, 1, 30, 49.18),
('2024-01-02'::date, 5, 2, 31, 50.82)
)
```
207 changes: 207 additions & 0 deletions docs/challenging-sql-problems/problems/gold/supply-chain-network.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
# Supply chain network 🚛

> [!SUCCESS] Scenario
>
> A supermarket's supply chain has three main components: stores, depots, and suppliers.
>
> In general, stock is sent from a supplier to a depot, and then from the depot to a store; however, there are cases where suppliers send stock directly to stores and depots send stock to other depots.
>
> For example:
>
> ```mermaid
> graph LR
> supplier_2 ----> store_6
> supplier_2 ---> depot_5
> supplier_2 ---> depot_4
> supplier_1 --> depot_3
> supplier_1 ---> depot_4
> depot_5 --> depot_4
> depot_5 ---> store_6
> depot_5 ---> store_7
> depot_5 ---> store_8
> depot_4 ---> store_6
> depot_4 ---> store_7
> depot_4 ---> store_8
> depot_3 --> depot_5
> depot_3 ---> store_6
> depot_3 ---> store_7
> depot_3 ---> store_8
> ```
>
> Although the supermarket knows how much stock is transported between locations, it doesn't know how much of each stock came from each supplier.
>
> This makes it difficult to report various metrics to the suppliers, like the stock balances and sales volumes of their products.
> [!QUESTION]
>
> Determine what the most likely proportion of stock in a store at the end of each day is from each supplier.
>
> Assume that stock moves in a queue ([first in, first out](https://en.wikipedia.org/wiki/Stock_rotation)) in both the depots and the stores.
>
> The output should have a row per store per supplier per day, with the columns:
>
> - `stock_date`
> - `store_id` as the ID of the store
> - `supplier_id` as the ID of the supplier
> - `stock_volume` as the derived volume of stock in the store from the supplier at the end of the day
> - `stock_proportion` as the derived proportion of stock in the store from the supplier. Express this as a percentage rounded to two decimal places
>
> Order the output by `stock_date`, `store_id`, and `supplier_id`.
>
> You can choose to show stores that have no stock from a supplier on a given day (i.e., you can show a row with a `stock_volume` of 0 or not show the row at all, whatever is easiest for you).
<details>
<summary>Expand for the DDL</summary>
--8<-- "docs/challenging-sql-problems/problems/gold/supply-chain-network.sql"
</details>
The solution can be found at:
- [supply-chain-network.md](../../solutions/gold/supply-chain-network.md)
A worked example is provided below to help illustrate the "shuffling" within the locations.
---
<!-- prettier-ignore -->
>? INFO: **Sample input**
>
> **Locations**
>
> | location_id | location_type |
> |------------:|:--------------|
> | 1 | supplier |
> | 2 | supplier |
> | 3 | depot |
> | 4 | depot |
> | 5 | store |
>
> **Deliveries**
>
> | delivery_date | from_location_id | to_location_id | product_id | quantity |
> |:--------------------|-----------------:|----------------:|-----------:|---------:|
> | 2024-01-01 01:23:53 | 1 | 3 | 123 | 25 |
> | 2024-01-01 06:27:54 | 2 | 4 | 123 | 25 |
> | 2024-01-01 12:27:39 | 4 | 5 | 123 | 25 |
> | 2024-01-01 17:12:59 | 1 | 3 | 123 | 30 |
> | 2024-01-02 01:27:57 | 3 | 5 | 123 | 25 |
> | 2024-01-02 05:16:08 | 3 | 4 | 123 | 30 |
> | 2024-01-02 05:40:53 | 2 | 3 | 123 | 20 |
> | 2024-01-02 07:29:53 | 1 | 4 | 123 | 30 |
> | 2024-01-02 09:22:53 | 3 | 5 | 123 | 20 |
> | 2024-01-02 18:28:39 | 4 | 5 | 123 | 60 |
>
> **Sales**
>
> | sale_datetime | store_id | product_id | quantity |
> |:--------------------|---------:|-----------:|---------:|
> | 2024-01-01 14:56:12 | 5 | 123 | 5 |
> | 2024-01-01 16:28:24 | 5 | 123 | 3 |
> | 2024-01-01 16:35:38 | 5 | 123 | 4 |
> | 2024-01-01 20:13:46 | 5 | 123 | 2 |
> | 2024-01-02 09:37:11 | 5 | 123 | 12 |
> | 2024-01-02 14:02:57 | 5 | 123 | 30 |
> | 2024-01-02 14:21:39 | 5 | 123 | 3 |
> | 2024-01-02 16:44:26 | 5 | 123 | 8 |
> | 2024-01-02 18:28:37 | 5 | 123 | 2 |
>
> **Network diagram**
>
> ```mermaid
> graph LR
> supplier_1 --> depot_3
> supplier_1 --> depot_4
> supplier_2 --> depot_3
> supplier_2 --> depot_4
> depot_3 --> depot_4
> depot_3 --> store_5
> depot_4 --> store_5
> ```
>
--8<-- "docs/challenging-sql-problems/problems/gold/supply-chain-network--sample-input.sql"
<!-- prettier-ignore -->
>? INFO: **Sample output**
>
>| stock_date | store_id | supplier_id | stock_volume | stock_proportion |
>|:-----------|---------:|------------:|-------------:|-----------------:|
>| 2024-01-01 | 5 | 1 | 0 | 0.00 |
>| 2024-01-01 | 5 | 2 | 11 | 100.00 |
>| 2024-01-02 | 5 | 1 | 30 | 49.18 |
>| 2024-01-02 | 5 | 2 | 31 | 50.82 |
>
--8<-- "docs/challenging-sql-problems/problems/gold/supply-chain-network--sample-output.sql"
<!-- prettier-ignore -->
>? TIP: **Hint 1**
>
> (to be added)
<!-- prettier-ignore -->
>? TIP: **Hint 2**
>
> (to be added)
---
### Worked example
To help illustrate the stock movement within the locations, consider the locations and deliveries in the **Sample input**.
We'll walk through each of the deliveries and how they contribute to end-of-day stock levels.
Since each delivery and sale correspond to the same product, we'll omit mentioning the product ID in the following walkthrough.
#### 2024-01-01
First, consider the deliveries:
- **Supplier 1** sends 25 units to **Depot 3**; **Depot 3** has 25 units from **Supplier 1** and 0 units from **Supplier 2**.
- **Supplier 2** sends 25 units to **Depot 4**; **Depot 4** has 0 units from **Supplier 1** and 25 units from **Supplier 2**.
- **Depot 4** sends 25 units to **Store 5**; all 25 units are originally from **Supplier 2** so:
- **Store 5** has 0 units from **Supplier 1** and 25 units from **Supplier 2**.
- **Depot 4** has 0 units from either supplier.
- **Supplier 1** sends 30 units to **Depot 3**; **Depot 3** has 55 units from **Supplier 1** and 0 units from **Supplier 2**.
Then the sales, which we can roll up to the end of the day:
- **Store 5** sells 14 units throughout the day; all units are from **Supplier 2** so **Store 5** has 0 units from **Supplier 1** and 11 units from **Supplier 2**.
Therefore, at the end of 2024-01-01, the proportion for **Store 5** is 100% from **Supplier 2**:
| stock_date | store_id | supplier_id | stock_volume | stock_proportion |
| :--------- | -------: | ----------: | -----------: | ---------------: |
| 2024-01-01 | 5 | 1 | 0 | 0.00 |
| 2024-01-01 | 5 | 2 | 11 | 100.00 |
#### 2024-01-02
First, consider the deliveries:
- **Depot 3** sends 25 units to **Store 5**; all 25 units are from **Supplier 2** so:
- **Store 5** has 0 units from **Supplier 1** and 36 units from **Supplier 2**.
- **Depot 3** has 30 units from **Supplier 1** and 0 units from **Supplier 2**.
- **Depot 3** sends 30 units to **Depot 4**; all 30 units are from **Supplier 2** so:
- **Depot 4** has 0 units from **Supplier 1** and 30 units from **Supplier 2**.
- **Depot 3** has 0 units from either supplier.
- **Supplier 2** sends 20 units to **Depot 3**; **Depot 3** has 20 units from **Supplier 2** and 0 units from **Supplier 1**.
- **Supplier 1** sends 30 units to **Depot 4**; **Depot 4** has 30 units from **Supplier 1** and 30 units from **Supplier 2**. The 30 units from **Supplier 2** and first in the queue, followed by the 30 units from **Supplier 1**.
- **Depot 3** sends 20 units to **Store 5**; all 20 units are from **Supplier 2** so:
- **Store 5** has 0 units from **Supplier 1** and 56 units from **Supplier 2**.
- **Depot 3** has 0 units from either supplier.
- **Depot 4** sends 60 units to **Store 5**; 30 units are from **Supplier 1** and 30 units are from **Supplier 2** so:
- **Store 5** has 30 units from **Supplier 1** and 86 units from **Supplier 2**. The existing 56 units from **Supplier 2** are first in the queue, followed by the new 30 units from **Supplier 2**, followed by the 30 units from **Supplier 1**.
- **Depot 4** has 0 units from either supplier.
Then the sales, which we can roll up to the end of the day:
- **Store 5** sells 55 units throughout the day; all 86 units from **Supplier 2** are first in the queue, so **Store 5** has 30 units from **Supplier 1** and 31 units from **Supplier 2**.
Therefore, at the end of 2024-01-02, the proportion for **Store 5** is 49.18% from **Supplier 1** and 50.82% from **Supplier 2**:
| stock_date | store_id | supplier_id | stock_volume | stock_proportion |
| :--------- | -------: | ----------: | -----------: | ---------------: |
| 2024-01-02 | 5 | 1 | 30 | 49.18 |
| 2024-01-02 | 5 | 2 | 31 | 50.82 |
Combined with the output from 2024-01-01, the output is the same as the **Sample output**.
Loading

0 comments on commit 195640d

Please sign in to comment.