comments | difficulty | edit_url | tags | |
---|---|---|---|---|
true |
Medium |
|
Table: Logs
+-------------+---------+ | Column Name | Type | +-------------+---------+ | id | int | | num | varchar | +-------------+---------+ In SQL, id is the primary key for this table. id is an autoincrement column starting from 1.
Find all numbers that appear at least three times consecutively.
Return the result table in any order.
The result format is in the following example.
Example 1:
Input: Logs table: +----+-----+ | id | num | +----+-----+ | 1 | 1 | | 2 | 1 | | 3 | 1 | | 4 | 2 | | 5 | 1 | | 6 | 2 | | 7 | 2 | +----+-----+ Output: +-----------------+ | ConsecutiveNums | +-----------------+ | 1 | +-----------------+ Explanation: 1 is the only number that appears consecutively for at least three times.
We can use two joins to solve this problem.
First, we perform a self-join with the condition l1.num = l2.num
and l1.id = l2.id - 1
, so that we can find all numbers that appear at least twice in a row. Then, we perform another self-join with the condition l2.num = l3.num
and l2.id = l3.id - 1
, so that we can find all numbers that appear at least three times in a row. Finally, we only need to select the distinct l2.num
.
import pandas as pd
def consecutive_numbers(logs: pd.DataFrame) -> pd.DataFrame:
all_the_same = lambda lst: lst.nunique() == 1
logs["is_consecutive"] = (
logs["num"].rolling(window=3, center=True, min_periods=3).apply(all_the_same)
)
return (
logs.query("is_consecutive == 1.0")[["num"]]
.drop_duplicates()
.rename(columns={"num": "ConsecutiveNums"})
)
# Write your MySQL query statement below
SELECT DISTINCT l2.num AS ConsecutiveNums
FROM
Logs AS l1
JOIN Logs AS l2 ON l1.id = l2.id - 1 AND l1.num = l2.num
JOIN Logs AS l3 ON l2.id = l3.id - 1 AND l2.num = l3.num;
We can use the window functions LAG
and LEAD
to obtain the num
of the previous row and the next row of the current row, and record them in the fields DISTINCT
keyword to remove duplicates from the results.
We can also group the numbers by using the IF
function to determine whether the num
of the current row is equal to the num
of the previous row. If they are equal, we set it to SUM
to calculate the prefix sum, which is the grouping identifier. Finally, we only need to group by the grouping identifier and filter out the numbers with a row count greater than or equal to DISTINCT
keyword to remove duplicates from the results.
# Write your MySQL query statement below
WITH
T AS (
SELECT
*,
LAG(num) OVER () AS a,
LEAD(num) OVER () AS b
FROM Logs
)
SELECT DISTINCT num AS ConsecutiveNums
FROM T
WHERE a = num AND b = num;
# Write your MySQL query statement below
WITH
T AS (
SELECT
*,
IF(num = (LAG(num) OVER ()), 0, 1) AS st
FROM Logs
),
S AS (
SELECT *, SUM(st) OVER (ORDER BY id) AS p
FROM T
)
SELECT DISTINCT num AS ConsecutiveNums
FROM S
GROUP BY p
HAVING COUNT(1) >= 3;