当某些状态发生变化时,如何从日志表中获取时间戳?

时间:2015-06-18 14:59:06

标签: mysql sql

我有一个状态更改列表,发生在不同的日期:

create table log (
  date date not null,
  state int not null default 0
);

insert into log (date, state) values
  ('2015-06-01', '0'),
  ('2015-06-05', '1'),
  ('2015-06-09', '1'),
  ('2015-06-10', '0'),
  ('2015-06-11', '0'),
  ('2015-06-14', '1'),
  ('2015-06-16', '1'),
  ('2015-06-26', '1'),
  ('2015-06-27', '0'),
  ('2015-06-28', '0'),
  ('2015-06-30', '1');

如何获得状态变化的日期对?

预期产出:

date 1,       date 2,       state 1,  state 2
'2015-06-01', '2015-06-05', 0,        1
'2015-06-09', '2015-06-10', 1,        0
'2015-06-11', '2015-06-14', 0,        1
'2015-06-26', '2015-06-27', 1,        0
'2015-06-28', '2015-06-30', 0,        1

1 个答案:

答案 0 :(得分:1)

状态变化的一个可能的查询是:

select pair.date as "date 1", pair.nextdate as "date 2", pair.state as "state 1", log.state as "state 2"
  from
    (select cur.*, min(next.date) as nextdate
      from log as cur
      join log as next on cur.date < next.date
      group by cur.date, cur.state) as pair
    join log on log.date = pair.nextdate
  where pair.state <> log.state;

<强>解释

通过在条件a.date < b.date上加入自己的日志,我们得到一个列表 对日期。

select * from log as cur
  join log as next on cur.date < next.date
  order by cur.date, next.date;


cur.date,     cur.state, next.date,    next.state
'2015-06-01', 0,         '2015-06-05', 1
'2015-06-01', 0,         '2015-06-09', 1
'2015-06-01', 0,         '2015-06-10', 0
'2015-06-01', 0,         '2015-06-11', 0
'2015-06-01', 0,         '2015-06-14', 1
'2015-06-01', 0,         '2015-06-16', 1
'2015-06-01', 0,         '2015-06-26', 1
'2015-06-01', 0,         '2015-06-27', 0
'2015-06-01', 0,         '2015-06-28', 0
'2015-06-01', 0,         '2015-06-30', 1
'2015-06-05', 1,         '2015-06-09', 1
'2015-06-05', 1,         '2015-06-10', 0

如果我们取最小值next.date,我们会得到之后日期的时间戳 cur.date

select cur.*, min(next.date) as "nextdate"
  from log as cur
  join log as next on cur.date < next.date
  group by cur.date, cur.state;

date,         state, nextdate
'2015-06-01', '0',   '2015-06-05'
'2015-06-05', '1',   '2015-06-09'
'2015-06-09', '1',   '2015-06-10'
'2015-06-10', '0',   '2015-06-11'
'2015-06-11', '0',   '2015-06-14'
'2015-06-14', '1',   '2015-06-16'
'2015-06-16', '1',   '2015-06-26'
'2015-06-26', '1',   '2015-06-27'
'2015-06-27', '0',   '2015-06-28'
'2015-06-28', '0',   '2015-06-30'

要获取state的{​​{1}},我们再次加入nextdate并过滤状态 变化(log)。