如何获取MYSQL8中列值更改之前第一次出现的选定行

如何获取MYSQL8中列值更改之前第一次出现的选定行,mysql,sql,window-functions,gaps-and-islands,mysql-8.0,Mysql,Sql,Window Functions,Gaps And Islands,Mysql 8.0,我有一个带有Event_TimeStamp和finalstate的MYSQL8表,看起来像这样 +---------------------------+---------------+ |"Event_TimeStamp" |"FinalState" | +---------------------------+---------------+ |"2020-03-09 04:57:45.729" |"Available" | |"2020-03-09 05:14

我有一个带有Event_TimeStamp和finalstate的MYSQL8表,看起来像这样

+---------------------------+---------------+
|"Event_TimeStamp"          |"FinalState"   |
+---------------------------+---------------+
|"2020-03-09 04:57:45.729"  |"Available"    |
|"2020-03-09 05:14:59.659"  |"Available"    |
|"2020-03-09 05:27:56.341"  |"Available"    |
|"2020-03-09 05:41:01.554"  |"Available"    |
|"2020-03-09 05:58:07.803"  |"Available"    |
|"2020-03-09 06:06:09.745"  |"Available"    |
|"2020-03-09 06:18:07.663"  |"Available"    |
|"2020-03-09 06:26:24.273"  |"Available"    |
|"2020-03-09 09:29:53.165"  |"Offline"      |
|"2020-03-09 10:28:00.514"  |"Available"    |
|"2020-03-09 12:47:54.130"  |"Available"    |
|"2020-03-09 13:01:30.117"  |"Available"    |
|"2020-03-09 13:01:59.774"  |"Offline"      |
|"2020-03-09 13:19:15.772"  |"Available"    |
|"2020-03-09 14:19:51.521"  |"Available"    |
|"2020-03-09 14:50:16.872"  |"Offline"      |
+---------------------------+---------------+
+---------------------------+---------------+-------------------+------------------+
|"Event_TimeStamp"          |"FinalState"   |"lag_final_state"  |"lead_final_state"|
+---------------------------+---------------+-------------------+------------------+
|"2019-11-18 02:01:16.395"  |"online"       |"offline"          |"online"          |
|"2019-11-18 04:34:59.739"  |"offline"      |"online"           |"online"          |
|"2019-11-18 04:45:08.354"  |"online"       |"offline"          |"online"          |
+---------------------------+---------------+-------------------+------------------+
我必须从上面提取行,这样它将有第一个可用的行和脱机的行,所以输出如下

+---------------------------+---------------+
|"Event_TimeStamp"          |"FinalState"   |
+---------------------------+---------------+
|"2020-03-09 04:57:45.729"  |"Available"    |
|"2020-03-09 09:29:53.165"  |"Offline"      |
|"2020-03-09 10:28:00.514"  |"Available"    |
|"2020-03-09 13:01:59.774"  |"Offline"      |
|"2020-03-09 13:19:15.772"  |"Available"    |
|"2020-03-09 14:50:16.872"  |"Offline"      |
+---------------------------+---------------+
我尝试了一些分组方式,但我只得到了每个最后状态的第一个条目,而没有得到其余条目


有没有一种方法可以通过一个查询来完成这项工作,或者我应该用PHP写出来?

可以使用连接。我使用事件作为数据库名称示例

选择x.* 来自事件x 参加 选择MINc.id 从事件a 左边 参加活动b 在b.FinalState=a.FinalState上 b.id=a.id-1 左边 参加活动c 在c.FinalState=a.FinalState上 和c.id>=a.id 左边 参加活动d 在d.FinalState=a.FinalState上 d.id=c.id+1 其中b.id为NULL 并且c.id不为空 d.id为空 组 凭身份证 Y y.id=x.id;
您可以使用lag函数检查状态是否发生变化:

with cte as
(select CAST('2020-03-09 04:57:45.729' as datetime) as Event_timestamp,'Available' as Finalstate union
select '2020-03-09 05:14:59.659','Available' union
select '2020-03-09 09:29:53.165','Offline' union
select '2020-03-09 10:28:00.514','Available')

select x.Event_timestamp,x.Finalstate
from
(select *,lag(Finalstate) Over(Order by Event_timestamp) as lag_status
from cte ) x
where x.Finalstate<>coalesce(lag_status,'Z')
这是一把db小提琴:

希望这有帮助。

您可以使用lag和lead来显示最终状态与前一行或下一行不同的记录:

select
    event_timestamp,
    final_state
from (
    select 
        t.*, 
        lag(final_state) over(order by event_timestamp)  lag_final_state,
        lead(final_state) over(order by event_timestamp) lead_final_state
    from mytable t
) t
where final_state <> lag_final_state or final_state <> lead_final_state

这个问题解决了我的问题。多亏了@

我将尽可能多地解释

首先,我们需要使用SELECT*运行查询,以查看出现的所有列

输出如下所示

+---------------------------+---------------+
|"Event_TimeStamp"          |"FinalState"   |
+---------------------------+---------------+
|"2020-03-09 04:57:45.729"  |"Available"    |
|"2020-03-09 05:14:59.659"  |"Available"    |
|"2020-03-09 05:27:56.341"  |"Available"    |
|"2020-03-09 05:41:01.554"  |"Available"    |
|"2020-03-09 05:58:07.803"  |"Available"    |
|"2020-03-09 06:06:09.745"  |"Available"    |
|"2020-03-09 06:18:07.663"  |"Available"    |
|"2020-03-09 06:26:24.273"  |"Available"    |
|"2020-03-09 09:29:53.165"  |"Offline"      |
|"2020-03-09 10:28:00.514"  |"Available"    |
|"2020-03-09 12:47:54.130"  |"Available"    |
|"2020-03-09 13:01:30.117"  |"Available"    |
|"2020-03-09 13:01:59.774"  |"Offline"      |
|"2020-03-09 13:19:15.772"  |"Available"    |
|"2020-03-09 14:19:51.521"  |"Available"    |
|"2020-03-09 14:50:16.872"  |"Offline"      |
+---------------------------+---------------+
+---------------------------+---------------+-------------------+------------------+
|"Event_TimeStamp"          |"FinalState"   |"lag_final_state"  |"lead_final_state"|
+---------------------------+---------------+-------------------+------------------+
|"2019-11-18 02:01:16.395"  |"online"       |"offline"          |"online"          |
|"2019-11-18 04:34:59.739"  |"offline"      |"online"           |"online"          |
|"2019-11-18 04:45:08.354"  |"online"       |"offline"          |"online"          |
+---------------------------+---------------+-------------------+------------------+
根据我的要求,我想知道下一个FinalState值,因此不需要final_state lead_final_state


我添加了COALESCE cause LEAD and LAG,它将为第一个SELECT查询之上或之外不存在的行提供空值。

您可以使用该方法对其进行CSS处理。选择表格。*,@t,@t:=FinalState,从表格join SELECT@t:=t1中选择@t FinalState这几乎可以完美地工作。我发布的答案基于您的查询。泰铢@GMB