Mysql me | TimeOn | TimeOff | x :---------- | :------- | :---------- | :------- | :------- | :------- 猴面包树|迪拉| 07:55:52 | 08:58:45 | 10:50:42 | 10:50:42 猴面包树|迪拉| 07:55:52 | 10:50:42 | 10:59:58 | 10:59:58 猴面包树|迪拉| 07:55:52 | 10:51:13 |空| 10:59:58 猴面包树|迪拉| 07:55:52 | 10:56:36 |空| 10:59:58 猴面包树|迪拉| 07:55:52 | 10:59:58 | 12:04:04 | 12:04:04 猴面包树|迪拉| 07:55:52 | 11:20:45 |空| 12:04:04 猴面包树|迪拉| 07:55:52 | 12:04:04 |空|空 制定电子计划|银行| 16:23:47 | 16:23:53 | 17:33:24 | 17:33:24 Make-e-plan | BANK | 16:23:47 | 17:33:24 | null | null 制作电子计划|银行| 16:23:47 | 18:50:07 |空|空

Mysql me | TimeOn | TimeOff | x :---------- | :------- | :---------- | :------- | :------- | :------- 猴面包树|迪拉| 07:55:52 | 08:58:45 | 10:50:42 | 10:50:42 猴面包树|迪拉| 07:55:52 | 10:50:42 | 10:59:58 | 10:59:58 猴面包树|迪拉| 07:55:52 | 10:51:13 |空| 10:59:58 猴面包树|迪拉| 07:55:52 | 10:56:36 |空| 10:59:58 猴面包树|迪拉| 07:55:52 | 10:59:58 | 12:04:04 | 12:04:04 猴面包树|迪拉| 07:55:52 | 11:20:45 |空| 12:04:04 猴面包树|迪拉| 07:55:52 | 12:04:04 |空|空 制定电子计划|银行| 16:23:47 | 16:23:53 | 17:33:24 | 17:33:24 Make-e-plan | BANK | 16:23:47 | 17:33:24 | null | null 制作电子计划|银行| 16:23:47 | 18:50:07 |空|空,mysql,join,Mysql,Join,D小提琴(mariadb_10.2) 顺便说一下,我没有让你的查询“按原样”工作,所以我无法比较结果 ---- 噢,当MySQL v8.x真正流行起来,并且它支持窗口函数,例如LAG()OVER和LEAD()OVER时,这个查询将更容易编写。如果您碰巧使用的是MariaDB或MySQL 8.x预发行版,您应该尝试使用这些窗口函数。如果您想“尝试”,我使用的dbfiddle确实支持这些函数。现在预期结果可用,我添加了一个不同的答案。我认为这更接近。我相信它可以像我以前的版本一样进行改进,但是(现在

D小提琴(mariadb_10.2)

顺便说一下,我没有让你的查询“按原样”工作,所以我无法比较结果

----
噢,当MySQL v8.x真正流行起来,并且它支持窗口函数,例如
LAG()OVER
LEAD()OVER
时,这个查询将更容易编写。如果您碰巧使用的是MariaDB或MySQL 8.x预发行版,您应该尝试使用这些窗口函数。如果您想“尝试”,我使用的dbfiddle确实支持这些函数。

现在预期结果可用,我添加了一个不同的答案。我认为这更接近。我相信它可以像我以前的版本一样进行改进,但是(现在)没有时间添加它了

在这个解决方案方法中,我将
(公共表表达式)结合使用,因此在支持
结合使用之前,MySQL版本还有第二个变体:

一起使用

groupname | observer |到达时间| TimeOn | TimeOff :---------- | :------- | :---------- | :------- | :------- 猴面包树|迪拉| 07:55:52 | 08:58:45 | 10:50:42 猴面包树|迪拉| 07:55:52 |空| 10:51:13 猴面包树|迪拉| 07:55:52 |空| 10:56:36 猴面包树|迪拉| 07:55:52 | 11:20:45 | 12:04:04 猴面包树|迪拉| 07:55:52 | 10:59:58 | 12:04:04 制定电子计划|银行| 16:23:47 | 16:23:53 | 17:33:24 Make-e-plan | BANK | 16:23:47 | null | 18:50:07
dbfiddle

感谢您的输入,与我的查询相比,它的设置似乎已经好了一点,但是不是期望的结果(我应该在示例数据中指定),请参见我的文章底部,在这里我显示了示例数据的期望结果。在您的结果中,时间在timeOff(记录1)和timeOn(记录2)之间重复,这也是我的一个问题。你知道如何克服这个问题吗?这似乎是一个近乎完美的解决方案。这里唯一的问题是第4行和第5行的12:04:04重复,我们假设当一行中有两条RecordON记录时,上的第一条记录将丢失RecordOFF记录,因此第4行应该为空(如我问题中的预期结果所示)。我们目前正在运行MySQL5.7,但是8.x版的方法似乎更简洁,我将很快启动一个虚拟机来测试它!我添加了一个Jon和我一直在研究的解决方案。它可能没有那么优雅,你对这个问题有什么建议吗?这是5.7版的版本,因为它在我们的环境中可以正常工作,直到它稳定后,我们将迁移到8.0。在你有可用的窗口函数之前,我看不到优化能力。我相信你的解决方案是基于这个评论上面的一个,所以我在这个问题上的想法很多。“接受”就足够了吗?
Rec ON/OFF | RecordTime
RecON      | 8:00:00
RecOFF     | 9:00:00
RecOFF     | 10:00:00
RecON      | 11:00:00
RecOFF     | 12:00:00
RecON      | 14:00:00
RecON      | 15:00:00
TimeRecON | TimeRecOFF
8:00      | 9:00
null      | 10:00
11:00     | 12:00
14:00     | null
15:00     | null
INSERT INTO `tbltest` (`id`,`GroupName`,`Observer`,`ArrivalTime`,`Behaviour`,`RecordTime`) VALUES (4865,'Make-e-plan','BANK','2017-08-26 16:23:47','RecON','16:23:53');
INSERT INTO `tbltest` (`id`,`GroupName`,`Observer`,`ArrivalTime`,`Behaviour`,`RecordTime`) VALUES (4878,'Make-e-plan','BANK','2017-08-26 16:23:47','RecOFF','17:33:24');
INSERT INTO `tbltest` (`id`,`GroupName`,`Observer`,`ArrivalTime`,`Behaviour`,`RecordTime`) VALUES (4890,'Make-e-plan','BANK','2017-08-26 16:23:47','RecOFF','18:50:07');
INSERT INTO `tblTest` (`id`,`GroupName`,`Observer`,`ArrivalTime`,`Behaviour`,`RecordTime`) VALUES (352,'Baobab','DILA','2017-08-16 07:55:52','RecON','08:58:45');
INSERT INTO `tblTest` (`id`,`GroupName`,`Observer`,`ArrivalTime`,`Behaviour`,`RecordTime`) VALUES (377,'Baobab','DILA','2017-08-16 07:55:52','RecOFF','10:50:42');
INSERT INTO `tblTest` (`id`,`GroupName`,`Observer`,`ArrivalTime`,`Behaviour`,`RecordTime`) VALUES (379,'Baobab','DILA','2017-08-16 07:55:52','RecOFF','10:51:13');
INSERT INTO `tblTest` (`id`,`GroupName`,`Observer`,`ArrivalTime`,`Behaviour`,`RecordTime`) VALUES (382,'Baobab','DILA','2017-08-16 07:55:52','RecOFF','10:56:36');
INSERT INTO `tblTest` (`id`,`GroupName`,`Observer`,`ArrivalTime`,`Behaviour`,`RecordTime`) VALUES (384,'Baobab','DILA','2017-08-16 07:55:52','RecON','10:59:58');
INSERT INTO `tblTest` (`id`,`GroupName`,`Observer`,`ArrivalTime`,`Behaviour`,`RecordTime`) VALUES (396,'Baobab','DILA','2017-08-16 07:55:52','RecON','11:20:45');
INSERT INTO `tblTest` (`id`,`GroupName`,`Observer`,`ArrivalTime`,`Behaviour`,`RecordTime`) VALUES (412,'Baobab','DILA','2017-08-16 07:55:52','RecOFF','12:04:04');
SELECT `id`, `GroupName`, `Observer`, `ArrivalTime`, `Behaviour`,   `RecOnTime`, `RecOffTime`, `PreviousContext`, `PreviousBehaviour`, `PreviousID`
FROM (
    SELECT `id`, `GroupName`, `Observer`, `ArrivalTime`, `Behaviour`, `RecordTime` `RecOfftime`, -- note that the recordtime is RecOFF here 
     @lastContext `PreviousContext`, 
    @lastBehaviour `PreviousBehaviour`, @lastid `PreviousID`,
        CASE 
            WHEN @lastBehaviour <> `Behaviour`                                   -- The previous record has to be RecON (this statement could be re-written to = "RecON")
                AND `Behaviour` = "RecOFF"
            THEN @lastRecordTime
            ELSE 
            CASE WHEN @lastBehaviour = 'RecON' AND `Behaviour`= 'RecON'             -- IF there are two RecON instances after each other without a RecOFF then put the previous instance as first RecON
            THEN @lastRecordTime
            ELSE "00:00:00"                                                         -- IF RecOn and RecOFF do not match enter 0
            END
        END                
        AS `RecOnTime`,
        @lastid := `id`,
        @lastRecordTime := TIME(`RecordTime`),
        @lastBehaviour := `Behaviour`,

    FROM `KMP_adlib_testing`.`tblAdlibRaw`
    WHERE `Behaviour` IN ('RecOn', 'RecOFF')                                        -- This pre-filters for only RecON and RecOFF behaviours
        AND `Observer` = @varObserver AND `GroupName` = @varGroupName AND ArrivalTime = @varArrivalTime
    ) as `tmp`
     WHERE  RecOnTime <> "00:00:00"                                                -- This filters all records where there is no RecON for the behaviours.. This could be re-entered as where the Context is null????
;
Group       | Observer | RecON    | RecOFF
Baobab      | DILA     | 08:58:45 | 10:50:42
Baobab      | DILA     | null     | 10:51:13
Baobab      | DILA     | null     | 10:56:36
Baobab      | DILA     | 10:59:58 | null     
Baobab      | DILA     | 11:20:45 | 12:04:04
Make-e-plan | BANK     | 16:23:53 | 17:33:24
Make-e-plan | BANK     | null     | 18:50:07
select   groupname
, observer
    , ArrivalTime
    , TimeOn
    , case INNER2.rownum_difference WHEN 1 THEN INNER2.TimeOff ELSE NULL END   AS TIMEOFF
FROM (
  SELECT
            groupname
          , observer
          , ArrivalTime
          , t1.RecordTime TimeOn
          , (SELECT
                    MIN(t2.RecordTime)
                  FROM tblAdlibPreProcessing t2
                  WHERE t2.GroupName = t1.GroupName
                  AND t2.Observer = t1.Observer
                  AND t2.Behaviour = 'RecOFF'
                  AND t2.RecordTime > t1.RecordTime
                  AND t2.GroupName = @groupname
                  AND t2.Observer = @observer
                  AND t2.ArrivalTime = @arrivaltime
            )      
            TimeOff
 -- This can remain out               
 --             , (SELECT id
 --                     FROM tbltest t3
 --                     WHERE  t3.RecordTime = (SELECT  MIN(t2.RecordTime)
 --                          FROM tblAdlibPreProcessing t2
 --                                              WHERE t2.GroupName = t1.GroupName
 --                                              AND t2.Observer = t1.Observer
 --                                              AND t2.Behaviour = 'RecOFF'
 --                                              AND t2.RecordTime > t1.RecordTime
 --                                              AND t2.GroupName = @groupname
 --                                              AND t2.Observer = @observer
 --                                              AND t2.ArrivalTime = @arrivaltime
 --                                              )
 --               ) rownum_time_off
 --               , t1.id as rownum_time_on
 -- End this can be left out
              , (SELECT id
                  FROM tblAdlibPreProcessing t3
                  WHERE 1=1
                  AND t3.GroupName = @groupname
        AND t3.Observer = @observer
                  AND t3.ArrivalTime = @arrivaltime
                  AND  t3.RecordTime = (SELECT  MIN(t2.RecordTime)
                      FROM tblAdlibPreProcessing t2
                                          WHERE t2.GroupName = t1.GroupName
                                          AND t2.Observer = t1.Observer
                                          AND t2.Behaviour = 'RecOFF'
                                          AND t2.RecordTime > t1.RecordTime
                                          AND t2.GroupName = @groupname
                                          AND t2.Observer = @observer
                                          AND t2.ArrivalTime = @arrivaltime
                                          )
            ) -  t1.id as rownum_difference
    FROM tblAdlibPreProcessing t1
    WHERE Behaviour = 'RecON'
    AND t1.GroupName = @groupname
    AND t1.Observer = @observer
    AND t1.ArrivalTime = @arrivaltime
) INNER2        
UNION ALL
SELECT
    ou.groupname
  , ou.observer
  , ou.ArrivalTime
  , NULL
  , ou.RecordTime
FROM ( 
    -- off_unpaired
    SELECT
            groupname
          , observer
          , ArrivalTime
          , t1.RecordTime
          , (SELECT
                    MAX(t2.RecordTime)
            FROM tblAdlibPreProcessing t2
            WHERE t2.GroupName = t1.GroupName
            AND t2.Observer = t1.Observer
            AND t2.Behaviour = 'RecON'
            AND t2.RecordTime < t1.RecordTime)
            max_t2_rt
    FROM tblAdlibPreProcessing t1
    WHERE Behaviour = 'RecOFF'
    AND t1.GroupName = @groupname
  AND t1.Observer = @observer
AND t1.ArrivalTime = @arrivaltime
 ) ou
LEFT JOIN ( 
    -- on_off_paired
    SELECT
            groupname
          , observer
          , ArrivalTime
          , t1.RecordTime TimeOn
          , (SELECT
                    MIN(t2.RecordTime)
            FROM tblAdlibPreProcessing t2
            WHERE t2.GroupName = t1.GroupName
            AND t2.Observer = t1.Observer
            AND t2.Behaviour = 'RecOFF'
            AND t2.RecordTime > t1.RecordTime
            AND t2.GroupName = @groupname
            AND t2.Observer = @observer
            AND t2.ArrivalTime = @arrivaltime)
            TimeOff
    FROM tblAdlibPreProcessing t1
    WHERE Behaviour = 'RecON'
 ) oop ON ou.groupname = oop.groupname
    AND ou.observer = oop.observer
    AND ou.ArrivalTime = oop.ArrivalTime
    AND ou.max_t2_rt = oop.TimeOn
    AND ou.RecordTime = oop.TimeOff
WHERE oop.groupname IS NULL
ORDER BY  1, 2, 3, 4, 5;
create table `tbltest` (`id` int,`GroupName` varchar(40),`Observer` varchar(40),`ArrivalTime` time,`Behaviour` varchar(20),`RecordTime` time);
INSERT INTO `tbltest` (`id`,`GroupName`,`Observer`,`ArrivalTime`,`Behaviour`,`RecordTime`)
VALUES
   (4865,'Make-e-plan','BANK','2017-08-26 16:23:47','RecON','16:23:53')
 , (4878,'Make-e-plan','BANK','2017-08-26 16:23:47','RecOFF','17:33:24')
 , (4890,'Make-e-plan','BANK','2017-08-26 16:23:47','RecOFF','18:50:07')
 , (352,'Baobab','DILA','2017-08-16 07:55:52','RecON','08:58:45')
 , (377,'Baobab','DILA','2017-08-16 07:55:52','RecOFF','10:50:42')
 , (379,'Baobab','DILA','2017-08-16 07:55:52','RecOFF','10:51:13')
 , (382,'Baobab','DILA','2017-08-16 07:55:52','RecOFF','10:56:36')
 , (384,'Baobab','DILA','2017-08-16 07:55:52','RecON','10:59:58')
 , (396,'Baobab','DILA','2017-08-16 07:55:52','RecON','11:20:45')
 , (412,'Baobab','DILA','2017-08-16 07:55:52','RecOFF','12:04:04');
select
  groupname,observer,ArrivalTime, t1.RecordTime
, (select min(t2.RecordTime)
   from tbltest t2
   where t2.GroupName = t1.GroupName and t2.Observer = t1.Observer
   and t2.Behaviour = 'RecOFF' and t2.RecordTime > t1.RecordTime) min_t2_rt
from tbltest t1
where Behaviour = 'RecON'
union all
select
  groupname,observer,ArrivalTime, t1.RecordTime
, (select min(t2.RecordTime)
   from tbltest t2
   where t2.GroupName = t1.GroupName and t2.Observer = t1.Observer
   and t2.Behaviour = 'RecON' and t2.RecordTime > t1.RecordTime) min_t2_rt
from tbltest t1
where Behaviour = 'RecOFF'
order by 1,2,3,4
groupname | observer | ArrivalTime | RecordTime | min_t2_rt :---------- | :------- | :---------- | :--------- | :-------- Baobab | DILA | 07:55:52 | 08:58:45 | 10:50:42 Baobab | DILA | 07:55:52 | 10:50:42 | 10:59:58 Baobab | DILA | 07:55:52 | 10:51:13 | 10:59:58 Baobab | DILA | 07:55:52 | 10:56:36 | 10:59:58 Baobab | DILA | 07:55:52 | 10:59:58 | 12:04:04 Baobab | DILA | 07:55:52 | 11:20:45 | 12:04:04 Baobab | DILA | 07:55:52 | 12:04:04 | null Make-e-plan | BANK | 16:23:47 | 16:23:53 | 17:33:24 Make-e-plan | BANK | 16:23:47 | 17:33:24 | null Make-e-plan | BANK | 16:23:47 | 18:50:07 | null
SELECT
      groupname
    , observer
    , ArrivalTime
    , TimeOn
    , IF(@prev_value=TimeOff, NULL, TimeOff) TimeOff
    , @prev_value := TimeOff x
FROM (
      SELECT
            groupname
          , observer
          , ArrivalTime
          , t1.RecordTime TimeOn
          , (
                  SELECT
                        MIN(t2.RecordTime)
                  FROM tbltest t2
                  WHERE t2.GroupName = t1.GroupName
                  AND t2.Observer = t1.Observer
                  AND t2.Behaviour = 'RecOFF'
                  AND t2.RecordTime > t1.RecordTime
            )
            TimeOff
      FROM tbltest t1
      WHERE Behaviour = 'RecON'
      UNION ALL
      SELECT
            groupname
          , observer
          , ArrivalTime
          , t1.RecordTime TimeOn
          , (
                  SELECT
                        MIN(t2.RecordTime)
                  FROM tbltest t2
                  WHERE t2.GroupName = t1.GroupName
                  AND t2.Observer = t1.Observer
                  AND t2.Behaviour = 'RecON'
                  AND t2.RecordTime > t1.RecordTime
            )
            TimeOff
      FROM tbltest t1
      WHERE Behaviour = 'RecOFF'
      ORDER BY
            groupname
          , observer
          , ArrivalTime
          , TimeOn
      ) d
CROSS JOIN (SELECT @row_num :=1,  @prev_value :='00:00:00') vars
groupname | observer | ArrivalTime | TimeOn | TimeOff | x :---------- | :------- | :---------- | :------- | :------- | :------- Baobab | DILA | 07:55:52 | 08:58:45 | 10:50:42 | 10:50:42 Baobab | DILA | 07:55:52 | 10:50:42 | 10:59:58 | 10:59:58 Baobab | DILA | 07:55:52 | 10:51:13 | null | 10:59:58 Baobab | DILA | 07:55:52 | 10:56:36 | null | 10:59:58 Baobab | DILA | 07:55:52 | 10:59:58 | 12:04:04 | 12:04:04 Baobab | DILA | 07:55:52 | 11:20:45 | null | 12:04:04 Baobab | DILA | 07:55:52 | 12:04:04 | null | null Make-e-plan | BANK | 16:23:47 | 16:23:53 | 17:33:24 | 17:33:24 Make-e-plan | BANK | 16:23:47 | 17:33:24 | null | null Make-e-plan | BANK | 16:23:47 | 18:50:07 | null | null
create table `tbltest` (`id` int,`GroupName` varchar(40),`Observer` varchar(40),`ArrivalTime` time,`Behaviour` varchar(20),`RecordTime` time);
INSERT INTO `tbltest` (`id`,`GroupName`,`Observer`,`ArrivalTime`,`Behaviour`,`RecordTime`)
VALUES
   (4865,'Make-e-plan','BANK','2017-08-26 16:23:47','RecON','16:23:53')
 , (4878,'Make-e-plan','BANK','2017-08-26 16:23:47','RecOFF','17:33:24')
 , (4890,'Make-e-plan','BANK','2017-08-26 16:23:47','RecOFF','18:50:07')
 , (352,'Baobab','DILA','2017-08-16 07:55:52','RecON','08:58:45')
 , (377,'Baobab','DILA','2017-08-16 07:55:52','RecOFF','10:50:42')
 , (379,'Baobab','DILA','2017-08-16 07:55:52','RecOFF','10:51:13')
 , (382,'Baobab','DILA','2017-08-16 07:55:52','RecOFF','10:56:36')
 , (384,'Baobab','DILA','2017-08-16 07:55:52','RecON','10:59:58')
 , (396,'Baobab','DILA','2017-08-16 07:55:52','RecON','11:20:45')
 , (412,'Baobab','DILA','2017-08-16 07:55:52','RecOFF','12:04:04');
WITH on_off_paired AS (
        SELECT
                groupname
              , observer
              , ArrivalTime
              , t1.RecordTime TimeOn
              , (SELECT
                        MIN(t2.RecordTime)
                FROM tbltest t2
                WHERE t2.GroupName = t1.GroupName
                AND t2.Observer = t1.Observer
                AND t2.Behaviour = 'RecOFF'
                AND t2.RecordTime > t1.RecordTime)
                TimeOff
        FROM tbltest t1
        WHERE Behaviour = 'RecON'
        )
, off_unpaired AS (
        SELECT
                groupname
              , observer
              , ArrivalTime
              , t1.RecordTime
              , (SELECT
                        MAX(t2.RecordTime)
                FROM tbltest t2
                WHERE t2.GroupName = t1.GroupName
                AND t2.Observer = t1.Observer
                AND t2.Behaviour = 'RecON'
                AND t2.RecordTime < t1.RecordTime)
                max_t2_rt
        FROM tbltest t1
        WHERE Behaviour = 'RecOFF'
        )
SELECT
        groupname
      , observer
      , ArrivalTime
      , TimeOn
      , TimeOff
FROM on_off_paired
UNION ALL
SELECT
        ou.groupname
      , ou.observer
      , ou.ArrivalTime
      , NULL
      , ou.RecordTime
FROM off_unpaired ou
LEFT JOIN on_off_paired oop ON ou.groupname = oop.groupname
        AND ou.observer = oop.observer
        AND ou.ArrivalTime = oop.ArrivalTime
        AND ou.max_t2_rt = oop.TimeOn
        AND ou.RecordTime = oop.TimeOff
WHERE oop.groupname IS NULL
ORDER BY 1, 2, 3, 5;
groupname | observer | ArrivalTime | TimeOn | TimeOff :---------- | :------- | :---------- | :------- | :------- Baobab | DILA | 07:55:52 | 08:58:45 | 10:50:42 Baobab | DILA | 07:55:52 | null | 10:51:13 Baobab | DILA | 07:55:52 | null | 10:56:36 Baobab | DILA | 07:55:52 | 11:20:45 | 12:04:04 Baobab | DILA | 07:55:52 | 10:59:58 | 12:04:04 Make-e-plan | BANK | 16:23:47 | 16:23:53 | 17:33:24 Make-e-plan | BANK | 16:23:47 | null | 18:50:07
-- where WITH is unavailable
SELECT
        groupname
      , observer
      , ArrivalTime
      , TimeOn
      , TimeOff
FROM (  
        -- on_off_paired
        SELECT
                groupname
              , observer
              , ArrivalTime
              , t1.RecordTime TimeOn
              , (SELECT
                        MIN(t2.RecordTime)
                FROM tbltest t2
                WHERE t2.GroupName = t1.GroupName
                AND t2.Observer = t1.Observer
                AND t2.Behaviour = 'RecOFF'
                AND t2.RecordTime > t1.RecordTime)
                TimeOff
        FROM tbltest t1
        WHERE Behaviour = 'RecON'
     ) D1
UNION ALL
SELECT
        ou.groupname
      , ou.observer
      , ou.ArrivalTime
      , NULL
      , ou.RecordTime
FROM ( 
        -- off_unpaired
        SELECT
                groupname
              , observer
              , ArrivalTime
              , t1.RecordTime
              , (SELECT
                        MAX(t2.RecordTime)
                FROM tbltest t2
                WHERE t2.GroupName = t1.GroupName
                AND t2.Observer = t1.Observer
                AND t2.Behaviour = 'RecON'
                AND t2.RecordTime < t1.RecordTime)
                max_t2_rt
        FROM tbltest t1
        WHERE Behaviour = 'RecOFF'
     ) ou
LEFT JOIN ( 
        -- on_off_paired
        SELECT
                groupname
              , observer
              , ArrivalTime
              , t1.RecordTime TimeOn
              , (SELECT
                        MIN(t2.RecordTime)
                FROM tbltest t2
                WHERE t2.GroupName = t1.GroupName
                AND t2.Observer = t1.Observer
                AND t2.Behaviour = 'RecOFF'
                AND t2.RecordTime > t1.RecordTime)
                TimeOff
        FROM tbltest t1
        WHERE Behaviour = 'RecON'
  ) oop ON ou.groupname = oop.groupname
        AND ou.observer = oop.observer
        AND ou.ArrivalTime = oop.ArrivalTime
        AND ou.max_t2_rt = oop.TimeOn
        AND ou.RecordTime = oop.TimeOff
WHERE oop.groupname IS NULL
ORDER BY 1, 2, 3, 5;
groupname | observer | ArrivalTime | TimeOn | TimeOff :---------- | :------- | :---------- | :------- | :------- Baobab | DILA | 07:55:52 | 08:58:45 | 10:50:42 Baobab | DILA | 07:55:52 | null | 10:51:13 Baobab | DILA | 07:55:52 | null | 10:56:36 Baobab | DILA | 07:55:52 | 11:20:45 | 12:04:04 Baobab | DILA | 07:55:52 | 10:59:58 | 12:04:04 Make-e-plan | BANK | 16:23:47 | 16:23:53 | 17:33:24 Make-e-plan | BANK | 16:23:47 | null | 18:50:07