Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add solutions to lc problem: No.1285 #1798

Merged
merged 1 commit into from
Oct 13, 2023
Merged
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
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"solution/1100-1199/1174.Immediate Food Delivery II/Solution.sql",
"solution/1100-1199/1193.Monthly Transactions I/Solution.sql",
"solution/1200-1299/1205.Monthly Transactions II/Solution.sql",
"solution/1200-1299/1285.Find the Start and End Number of Continuous Ranges/Solution.sql",
"solution/1300-1399/1384.Total Sales Amount by Year/Solution.sql",
"solution/1300-1399/1322.Ads Performance/Solution.sql",
"solution/1300-1399/1393.Capital GainLoss/Solution.sql",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,51 @@ Logs 表:

<!-- 这里可写通用的实现逻辑 -->

**方法一:分组 + 窗口函数**

我们需要想办法将一段连续的日志分到同一组,然后对每一组进行聚合操作,得到每一组的开始日志和结束日志。

分组可以用以下两种方法实现:

1. 通过计算每个日志与前一个日志的差值,如果差值为 $1$,则说明这两个日志是连续的,我们设置 $delta$ 为 $0$,否则设置为 $1$。然后我们对 $delta$ 求前缀和,得到的结果就是每一行的分组的标识符。
2. 通过计算当前行的日志减去当前行的行号,得到的结果就是每一行的分组的标识符。

<!-- tabs:start -->

### **SQL**

```sql
SELECT
MIN(log_id) AS start_id,
MAX(log_id) AS end_id
FROM
(
# Write your MySQL query statement below
WITH
T AS (
SELECT
log_id,
sum(delta) OVER (ORDER BY log_id) AS pid
FROM
(
SELECT
log_id,
if((log_id - lag(log_id) OVER (ORDER BY log_id)) = 1, 0, 1) AS delta
FROM Logs
) AS t
)
SELECT min(log_id) AS start_id, max(log_id) AS end_id
FROM T
GROUP BY pid;
```

```sql
# Write your MySQL query statement below
WITH
T AS (
SELECT
log_id,
log_id - ROW_NUMBER() OVER (ORDER BY log_id) AS rk
log_id - row_number() OVER (ORDER BY log_id) AS pid
FROM Logs
) AS t
GROUP BY rk;
)
SELECT min(log_id) AS start_id, max(log_id) AS end_id
FROM T
GROUP BY pid;
```

<!-- tabs:end -->
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,51 @@ Number 10 is contained in the table.

## Solutions

**Solution 1: Group By + Window Function**

We need to find a way to group a continuous sequence of logs into the same group, and then aggregate each group to obtain the start and end logs of each group.

There are two ways to implement grouping:

1. By calculating the difference between each log and the previous log, if the difference is $1$, then the two logs are continuous, and we set $delta$ to $0$, otherwise we set it to $1$. Then we take the prefix sum of $delta$ to obtain the grouping identifier for each row.
2. By calculating the difference between the current log and its row number, we obtain the grouping identifier for each row.

<!-- tabs:start -->

### **SQL**

```sql
SELECT
MIN(log_id) AS start_id,
MAX(log_id) AS end_id
FROM
(
# Write your MySQL query statement below
WITH
T AS (
SELECT
log_id,
sum(delta) OVER (ORDER BY log_id) AS pid
FROM
(
SELECT
log_id,
if((log_id - lag(log_id) OVER (ORDER BY log_id)) = 1, 0, 1) AS delta
FROM Logs
) AS t
)
SELECT min(log_id) AS start_id, max(log_id) AS end_id
FROM T
GROUP BY pid;
```

```sql
# Write your MySQL query statement below
WITH
T AS (
SELECT
log_id,
log_id - ROW_NUMBER() OVER (ORDER BY log_id) AS rk
log_id - row_number() OVER (ORDER BY log_id) AS pid
FROM Logs
) AS t
GROUP BY rk;
)
SELECT min(log_id) AS start_id, max(log_id) AS end_id
FROM T
GROUP BY pid;
```

<!-- tabs:end -->
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
SELECT
MIN(log_id) AS start_id,
MAX(log_id) AS end_id
FROM
(
# Write your MySQL query statement below
WITH
T AS (
SELECT
log_id,
log_id - ROW_NUMBER() OVER (ORDER BY log_id) AS rk
log_id-row_number() OVER (ORDER BY log_id) AS pid
FROM Logs
) AS t
GROUP BY rk;
)
SELECT min(log_id) AS start_id, max(log_id) AS end_id
FROM T
GROUP BY pid;