力扣-SQL 180连续出现的数字

本来这种中等题目是不值得特地写在文章中的,但是看到其中有一个题解使用窗口函数来解决连续出现N次数字的方法,并且在过程中遇到了比较有趣的问题,就在此记录一下

题目:

表:Logs

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| num         | varchar |
+-------------+---------+
在 SQL 中,id 是该表的主键。
id 是一个自增列。

找出所有至少连续出现三次的数字。

返回的结果表中的数据可以按 任意顺序 排列。

示例 1:

输入:
Logs 表:
+----+-----+
| id | num |
+----+-----+
| 1  | 1   |
| 2  | 1   |
| 3  | 1   |
| 4  | 2   |
| 5  | 1   |
| 6  | 2   |
| 7  | 2   |
+----+-----+
输出:
Result 表:
+-----------------+
| ConsecutiveNums |
+-----------------+
| 1               |
+-----------------+
解释:1 是唯一连续出现至少三次的数字。

题解:

with t1 as (
    select id, num,
    id - cast(row_number() over (partition by num order by id) as signed) as s_id
    from Logs
    order by num asc
)
select distinct num as ConsecutiveNums
from t1
group by num, s_id
having count(*) >= 3;

这里使用有趣的窗口函数按num进行分组row_number()自增并使用id减去这个分组的row_number()组,假如是连续的num,那么id-自增id得到的差应该是一样的,那么在这个基础上,对numdiff进行group by having count(*)就能求出(num,diff)一样的和的数量,这样只需要设置 having count(*)的数目,即可确定连续出现N次的数字/内容。

有趣的内容:当我在直接使用id-row_number() over (partition by num order by id) 出现了一个错误提示: BIGINT UNSIGNED value is out of range in `(t.id - t.rnk)`

在MySQL中,如果你对两个整数进行减法运算,其中一个整数是 UNSIGNED 类型,默认情况下结果也会被视为 UNSIGNED。这意味着如果结果本来是负数,由于 UNSIGNED 类型不能表示负数,你会得到一个错误的结果。例如:SELECT CAST(1 AS UNSIGNED) - 2;

在这个例子中,1 被转换为 UNSIGNED 类型,然后减去 2,结果应该是 -1。但是由于结果被视为 UNSIGNED,MySQL会返回一个非常大的正数,而不是负数。

所以在上述的题解中,使用了cast 将row_number()转换为了signed有符号类型即可解决这个错误。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇