提问人:Squidonis 提问时间:8/9/2022 更新时间:8/9/2022 访问量:145
使用 SQL 查找连续日期组中的最长递增序列
Find longest increasing sequence in groups of consecutive dates using SQL
问:
使用 MARIA-DB 10.6
我有一个包含列和每行的表。日期将始终是唯一的(任何日期只有 1 行,如果存在)。随着日期的滚动,已解决的计数可以相同或更高。user
dates
solved
下面是一个示例表:user
日期 | 解决 |
---|---|
2010-11-26 | 2 |
2010-11-27 | 4 |
2010-11-28 | 6 |
2010-11-29 | 10 |
2010-12-05 | 11 |
2010-12-06 | 11 |
2010-12-07 | 11 |
2010-12-08 | 12 |
2010-12-09 | 12 |
2010-12-10 | 12 |
我需要从中找到的是:最长的连续日期序列,其中已解决的计数正在增加。
现在我处理它的方式是,这有两个部分。第一部分是找到连续天数的组。在这篇文章之后,我通过这个查询实现了这一点:
WITH consecutiveDateGroups AS (
SELECT
ROW_NUMBER() OVER (ORDER BY date) AS rowNum,
DATE_ADD(date, INTERVAL (-ROW_NUMBER() OVER (ORDER BY date)) DAY) AS consecutiveDateGroup,
date,
solved
FROM user
)
SELECT *
FROM consecutiveDateGroups
ORDER BY rowNum
就我而言,我们有 3 组连续日期:
[第 1 组] -> 2010-11-26 至 2010-11-29 (4 天)
[第 2 组] -> 2010-12-05 至 2010-12-10 (6 天)
我可以使用此查询按每个组中的连续天数进行分组:
WITH
consecutiveDateGroups AS (
SELECT
ROW_NUMBER() OVER (ORDER BY date) AS rowNum,
DATE_ADD(date, INTERVAL (-ROW_NUMBER() OVER (ORDER BY date)) DAY) AS consecutiveDateGroup,
date
FROM user
)
SELECT
COUNT(*) AS consecutiveDates,
MIN(date) AS minDate,
MAX(date) AS maxDate
FROM consecutiveDateGroups
GROUP BY consecutiveDateGroup
到目前为止,我得到的结果是:
consecutiveDates | 最小日期 | 最大日期 |
---|---|---|
4 | 2010-11-26 | 2010-11-29 |
6 | 2010-12-05 | 2010-12-10 |
到目前为止,我一切都很好。但在此之后,事情对我来说变得泥泞,我被困住了。如何返回每个连续日期组的已解决列数?
例如,在本例中:
[第 1 组] 的序列递增为 4 [2,4,6,10]
[第2组]的序列递增为2个[11,12]
所以我想要的结果是:
consecutiveDates | 最小日期 | 最大日期 | 增加已解决序列 |
---|---|---|---|
4 | 2010-11-26 | 2010-11-29 | 4 |
6 | 2010-12-05 | 2010-12-10 | 2 |
任何帮助将不胜感激!
小提琴:https://dbfiddle.uk/?rdbms=mariadb_10.6&fiddle=c80ffb091bb272b0c3b2ae8abbbbbaf1
答:
2赞
ahmed
8/9/2022
#1
请尝试以下操作:
set @cn = 1;
WITH consecutiveDateGroups AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY date) AS rowNum,
DATE_ADD(date, INTERVAL (-ROW_NUMBER() OVER (ORDER BY date)) DAY) AS consecutiveDateGroup,
date,
solved
FROM user
)
,
cte AS
(
SELECT *,
COALESCE(LEAD(solved) OVER (PARTITION BY consecutiveDateGroup ORDER BY date), solved) AS LD
FROM consecutiveDateGroups
ORDER BY rowNum
),
cte2 as
(
SELECT *,
CASE WHEN solved <> ld THEN @cn:=@cn+1 ELSE @cn:=1 END AS ch
FROM cte
)
SELECT
COUNT(*) AS consecutiveDates,
MIN(date) AS minDate,
MAX(date) AS maxDate,
MAX(ch) AS increasingSolvedSequence
FROM cte2
GROUP BY consecutiveDateGroup
观看 db<>fiddle 的演示。
评论
0赞
Squidonis
8/9/2022
感谢您抽出宝贵时间回答。遗憾的是,DISTINCT(solved) 不会涵盖日期组具有许多不同已解决计数的情况,但它们不一定在增加。就像在这种情况下:[2,4,6,10] ->最长的 inc. seq 在这里是 4 而 [11,11,12,12,13,13,14,14,15,15,16,16] 最长的 inc. seq 在这里是 2。小提琴来证明这一点:dbfiddle.uk/......
1赞
ahmed
8/9/2022
你能解释一下什么是最长的递增序列吗,我以为是已解的不同值。
0赞
Squidonis
8/9/2022
递增序列是一系列数字,其中每个数字都高于前一个数字。像 [1,2,3,4] 是一系列递增的数字,因为 2>1、3>2、4>3。然而,[1,2,2,3] 不是一个真正的递增序列,因为中间有 2,2。2 不大于 2,因此中间重复 2 会破坏序列。希望这是有道理的。
1赞
ahmed
8/9/2022
答案已更新,请检查一下,让我知道是否可以。
1赞
Squidonis
8/10/2022
非常感谢艾哈迈德!这非常有效。经过多天的挣扎,你帮助我摆脱了困境。说真的,谢谢!!!!!!!!
评论