Description
Table: Stadium
| Column Name | Type |
|---|---|
| id | int |
| visit_date | date |
| people | int |
visit_dateis the column with unique values for this table.- Each row of this table contains the visit date and visit id to the stadium with the number of people during the visit.
- As the
idincreases, the date increases as well.
Problem Statement
Write a solution to display the records with three or more rows with consecutive id’s, and the number of people is greater than or equal to 100 for each.
Return the result table ordered by visit_date in ascending order.
The result format is in the following example.
Example 1:
Input:
Stadiumtable
| id | visit_date | people |
|---|---|---|
| 1 | 2017-01-01 | 10 |
| 2 | 2017-01-02 | 109 |
| 3 | 2017-01-03 | 150 |
| 4 | 2017-01-04 | 99 |
| 5 | 2017-01-05 | 145 |
| 6 | 2017-01-06 | 1455 |
| 7 | 2017-01-07 | 199 |
| 8 | 2017-01-09 | 188 |
Output:
| id | visit_date | people |
|---|---|---|
| 5 | 2017-01-05 | 145 |
| 6 | 2017-01-06 | 1455 |
| 7 | 2017-01-07 | 199 |
| 8 | 2017-01-09 | 188 |
Explanation:
- The four rows with ids 5, 6, 7, and 8 have consecutive ids and each of them has
>= 100people attended. Note that row 8 was included even though thevisit_datewas not the next day after row 7. - The rows with ids 2 and 3 are not included because we need at least three consecutive ids.
Solution
The problem can be divided into following parts:
- First of all, you need to find only those rows for which
people >= 100. So, you need to filter the rows wherepeople >= 100.
1SELECT *
2 FROM Stadium
3 WHERE people >= 100;
- You need to output rows which have consecutive ids. The three subsequent ids can be either the current and two previous, current, previous and next or current and next two. Now, in order to get previous two values, you can get them using
LAG(id, 1)andLAG(id, 2). In order to get next two ids, you can useLEAD(id, 1)andLEAD(id, 2).
1SELECT id, visit_date, people,
2 LAG(id, 1) OVER (ORDER BY id) AS previous_id,
3 LAG(id, 2) OVER (ORDER BY id) AS second_previous_id,
4 LEAD(id, 1) OVER (ORDER BY id) AS next_id,
5 LEAD(id, 2) OVER (ORDER BY id) AS second_next_id
6 FROM Stadium
7 WHERE people >= 100;
- Once you’ve got consecutive ids, you have to output rows where the difference between ids is 1. This will ensure that the ids are consecutive ids. You can use
WHEREclause for this.
1WHERE (
2 (id - previous_id = 1 AND previous_id - second_previous_id = 1) OR
3 (id - previous_id = 1 AND next_id - id = 1) OR
4 (second_next_id - next_id = 1 AND next_id - id = 1)
5) ORDER BY visit_date;
The final solution looks like below.
1WITH tmp AS (
2 SELECT id, visit_date, people,
3 LAG(id, 1) OVER (ORDER BY id) AS previous_id,
4 LAG(id, 2) OVER (ORDER BY id) AS second_previous_id,
5 LEAD(id, 1) OVER (ORDER BY id) AS next_id,
6 LEAD(id, 2) OVER (ORDER BY id) AS second_next_id
7 FROM Stadium
8 WHERE people >= 100
9) SELECT id, visit_date, people
10 FROM tmp
11 WHERE (
12 (id - previous_id = 1 AND previous_id - second_previous_id = 1) OR
13 (id - previous_id = 1 AND next_id - id = 1) OR
14 (second_next_id - next_id = 1 AND next_id - id = 1)
15 ) ORDER BY visit_date;


Comments