MYSQL select 在值小于前一天值的情况下让用户明智地获取连续天数

MYSQL select to get Consecutive Day Count user wise where the value is lesser than previous day value

MySqlV 8.0

问题:如何写 MySQL select 来获得连续的天数,其中重量值小于前一天的重量值用户明智,当不再连续或重量值相同时中断或大于同一用户前一天的权重值。

create table userData (recordDate ,userName varchar(100), weight FLOAT);
insert into userData (recordDate, userName, weight)
values
    ('2020/8/1','Chris', 78),
    ('2021/8/2','Chris', 77),
    ('2021/8/3','Chris', 76),
    ('2021/8/1','Aamir', 78),
    ('2021/8/2','Aamir', 77),
    ('2021/8/1','Alex', 78),
    ('2021/8/2','Alex', 77),
    ('2021/8/3','Alex', 76),
    ('2021/8/5','Chris', 78),
    ('2021/8/6','Chris', 77),
    ('2021/8/7','Chris', 76),
    ('2021/8/8','Chris', 75),
    ('2021/8/8','Aamir', 78), 
    ('2021/8/8','Alex', 78),
    ('2021/8/9','John', 78),
    ('2021/8/1','Ali', 78),
    ('2021/8/10','Chris', 78);

预期输出为

| userName | streakDays | startingDate | endingDate |  
| -------- | ---------- | ------------ | ---------- |  
| Alex     | 3          | 2021-08-01   | 2021-08-03 | 
| Chris    | 3          | 2021-08-06   | 2021-08-08 | 
| Aamir    | 2          | 2021-08-01   | 2021-08-02 | 
| Ali      | 1          | 2021-08-01   | 2021-08-01 | 
| John     | 1          | 2021-08-09   | 2021-08-09 | 

如有任何帮助,我们将不胜感激。

根据您在 table 中插入的数据,此 Select 查询工作正常

select userName as un , 
count((select recordDate WHERE userName = un)) as strekdays,
(select recordDate FROM userdata WHERE userName = un limit 1)  as startdate ,
(select recordDate FROM userdata WHERE userName = un order by recordDate DESC limit 1)  as enddate
from userdata
group by userName

它给出的输出类似于

userName streakDays startingDate endingDate
Aamir 3 2021-08-01 2021-08-08
Alex 4 2021-08-01 2021-08-08
Ali 1 2021-08-01 2021-08-01
Chris 8 2021-08-01 2021-08-10
John 1 2021-08-09 2021-08-09

让我知道这是否适合您!

问题已通过以下查询解决

select
   streakBreakersRemoved.userName,
   streakBreakersRemoved.streakDays,
   streakBreakersRemoved.startingDate,
   streakBreakersRemoved.endingDate 
from
   (
      select
         userName,
         count(*) as streakDays,
         min(recordDate) as startingDate,
         max(recordDate) as endingDate,
         row_number() over (partition by userName 
      order by
         count(*) desc) as seqNum 
      from
         (
            select
               initailRecords.*,
               row_number() over (partition by userName 
            order by
               recordDate) as initialSeqNum 
            from
               (
                  select
                     userData.*,
                     lag(weight) over (partition by userName 
                  order by
                     recordDate) as previousWeight 
                  from
                     userData 
               )
               initailRecords 
            where
               if(previousWeight is null || previousWeight > weight, 1, 0) = 1 
         )
         recordsWithSeqNum 
      group by
         userName,
         to_days(recordDate) - initialSeqNum 
   )
   streakBreakersRemoved 
where
   seqNum = 1 
order by
   streakDays desc;

如果有人愿意优化上述查询,我​​们将不胜感激。