返回介绍

solution / 1200-1299 / 1285.Find the Start and End Number of Continuous Ranges / README

发布于 2024-06-17 01:03:21 字数 2306 浏览 0 评论 0 收藏 0

1285. 找到连续区间的开始和结束数字

English Version

题目描述

表:Logs

+---------------+---------+
| Column Name   | Type  |
+---------------+---------+
| log_id    | int   |
+---------------+---------+
id 是上表具有唯一值的列。
上表的每一行包含日志表中的一个 ID。

 

编写解决方案,得到 Logs 表中的连续区间的开始数字和结束数字。

返回结果表按照 start_id 排序。

结果格式如下面的例子。

 

示例 1:

输入:
Logs 表:
+------------+
| log_id   |
+------------+
| 1      |
| 2      |
| 3      |
| 7      |
| 8      |
| 10     |
+------------+
输出:
+------------+--------------+
| start_id   | end_id     |
+------------+--------------+
| 1      | 3      |
| 7      | 8      |
| 10     | 10       |
+------------+--------------+
解释:
结果表应包含 Logs 表中的所有区间。
从 1 到 3 在表中。
从 4 到 6 不在表中。
从 7 到 8 在表中。
9 不在表中。
10 在表中。

解法

方法一:分组 + 窗口函数

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

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

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

方法二

# Write your MySQL query statement below
WITH
  T AS (
    SELECT
      log_id,
      log_id - ROW_NUMBER() OVER (ORDER BY log_id) AS pid
    FROM Logs
  )
SELECT MIN(log_id) AS start_id, MAX(log_id) AS end_id
FROM T
GROUP BY pid;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文