-2

I have a table in a mysql database that tracks changes in settings. Looks like this:

date setting 1 setting 2
2021-01-02 0.01 0.00
2021-01-03 0.02 0.00
2021-01-04 0.03 0.00
2021-01-05 0.04 0.00
2021-01-06 0.04 0.01
2021-01-07 0.03 0.01
2021-01-08 0.04 0.01
2021-01-09 0.04 0.02
2021-01-10 0.05 0.02
2021-01-11 0.06 0.02
2021-01-12 0.06 0.00
2021-01-13 0.07 0.00
2021-01-14 0.08 0.00
2021-01-15 0.08 0.01

I'm looking to get all dates on which 'Setting 2' has changed. Expected result:

date setting 1 setting 2
2021-01-02 0.01 0.00
2021-01-06 0.04 0.01
2021-01-09 0.04 0.02
2021-01-12 0.06 0.00
2021-01-15 0.08 0.01

Any suggestions please?

4 Answers4

1

Run:

SELECT `date`,setting1,setting2 FROM  ( SELECT  *,
                        IF(@prevStatus = s.setting2, @rn := @rn + 1,
                        IF(@prevStatus := s.setting2, @rn := 1, @rn := 1) ) AS rn
                FROM setting s
         CROSS JOIN 
                (
                 SELECT @prevStatus := -1, @rn := 1
                ) AS var 
        ORDER BY s.`date`
               ) AS t
        WHERE t.rn = 1
        ORDER BY t.`date` ;

Demo: https://www.db-fiddle.com/f/7yUJcuMJPncBBnrExKbzYz/1

All credential to user: @1000111 : Mysql select row when column value changed

Ergest Basha
  • 7,870
  • 4
  • 8
  • 28
1

As you are interested in a window function solution, this will work in MySQL 8, or any platform that supports ansi window functions.

select date, setting1, setting2 from (
    select *, case when Lag(setting2,1,-1) over(order by date) != setting2 then 1 end changed
    from t
)t
where changed=1
Stu
  • 30,392
  • 6
  • 14
  • 33
1

In MySQL 8+, you can use lag(). I would phrase this as:

select t.*
from (select t.*,
             lag(setting2) over (order by date) as prev_setting2
      from t
     ) t
where not prev_setting2 <=> setting2;

Note that <=> is the null-safe comparison operator.

If you are using an older version of MySQL, well, at this point I would recommend that you upgrade.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
0

my solution

SELECT date,setting1,setting2 FROM 
( SELECT *,
  IF(@prevStatus = YT.setting2, @rn := @rn + 1,
    IF(@prevStatus := YT.setting2, @rn := 1, @rn := 1)
  ) AS rn
 FROM your_table YT
 CROSS JOIN 
 (
  SELECT @prevStatus := -1, @rn := 1
 ) AS var 
 ORDER BY YT.date
) AS t
WHERE t.rn = 1
ORDER BY t.ID

from this post

hongnhat
  • 157
  • 2
  • 2
  • 12