Select 对话开始和结束之间范围内的数据(使用 SQL / H2 数据库进行聊天记录分析)

Select data from range between conversational openings and closings (chat log analysis using SQL / H2 Database)

我有一个名为 "conversations" 的 table,它包含这样的数据:

 TIMESTAMP       | ACTOR| CONTEXT| MESSAGE    | CLASSIFICATION
-----------------+------+--------+------------+-----------
01.02.2015 09:38 | user | text   | blablabla  | normal
01.02.2015 09:46 | bot  | text   | blablabla  | normal
01.02.2015 10:19 | user | text   | hi bot!    | opening
01.02.2015 10:20 | bot  | text   | blablabla  | normal
01.02.2015 10:21 | user | text   | blablabla  | normal
01.02.2015 10:22 | bot  | text   | blablabla  | normal
01.02.2015 10:23 | user | text   | ok bye bot | closing
01.02.2015 11:53 | bot  | text   | blablabla  | normal
01.02.2015 12:14 | user | text   | goodbye    | closing
01.02.2015 12:33 | bot  | text   | blablabla  | normal
01.02.2015 12:51 | bot  | text   | blablabla  | normal

我想要 SELECT 是我的数据集中 'openings' 和 'closings' 之间的范围,以便将成功构建的对话与所有其他用户输入/机器人输出分开。

预期输出为:

 TIMESTAMP       | ACTOR| CONTEXT| MESSAGE    | CLASSIFICATION
-----------------+------+--------+------------+-----------
01.02.2015 10:19 | user | text   | hi bot!    | opening
01.02.2015 10:20 | bot  | text   | blablabla  | normal
01.02.2015 10:21 | user | text   | blablabla  | normal
01.02.2015 10:22 | bot  | text   | blablabla  | normal
01.02.2015 10:23 | user | text   | ok bye bot | closing

------------更新

我执行了评论中提出的查询,但 H2 没有输出任何数据:

Output_Info

谢谢!

select * 
from
    (select
        t.*,
        case when @rangeStarted=1 then 1 else 0 end as inside_range,
        @rangeStarted:=case 
                         when CLASSIFICATION='opening' then 1
                         when CLASSIFICATION='normal' then @rangeStarted
                         when CLASSIFICATION='closing' then 0
                       end 
    from t, (select @rangeStarted:=0)
    order by TIMESTAMP) sub
where inside_range=1

我们定义一个基于行的变量(最初为0)。当我们遇到 'opening' 时变量设置为 1,当我们遇到 'closing'.

时重置回 0

那就只留下变量为1的记录

更新:在子查询逻辑中放置顺序

更新 2:

select
        t.*,
        case when @rangeStarted=1 OR CLASSIFICATION='opening' then 1 else 0 end as inside_range,
        @rangeStarted:=case 
                         when CLASSIFICATION='opening' then 1
                         when CLASSIFICATION='normal' then @rangeStarted
                         when CLASSIFICATION='closing' then 0
                       end  as r
from Table1 t, (select @rangeStarted:=0) as var
order by TIMESTAMP

在 Juan Carlos Oropeza 提供的测试中更正和测试了内部范围

为了解决这个问题,我假设你是一个 Date,你需要在左括号和右括号之间,所以:

(OPEN   date   CLOSE)

从这里你有:date >= OPEN and date <= CLOSE

但对于这种情况:OPEN date1 CLOSE date2 CLOSE

您需要检查 date2 有没有关闭的打开:nearLeftOpen > nearLeftClose

所以最后的逻辑变成了:

SQL DEMO:

SELECT t1.*
FROM Table1 t1
WHERE t1.TIMESTAMP >= (SELECT MAX(IF (CLASSIFICATION='opening', TIMESTAMP, null))
                       FROM Table1 t2
                       WHERE t2.TIMESTAMP <= t1.TIMESTAMP)
  AND t1.TIMESTAMP <= (SELECT MIN(IF (CLASSIFICATION='closing', TIMESTAMP, null))
                       FROM Table1 t3
                       WHERE t3.TIMESTAMP >= t1.TIMESTAMP)      
  AND (SELECT MAX(IF (CLASSIFICATION='opening', TIMESTAMP, null))
       FROM Table1 t2
       WHERE t2.TIMESTAMP <= t1.TIMESTAMP) > 
      (SELECT MAX(IF (CLASSIFICATION='closing', TIMESTAMP, '1900-01-01'))
       FROM Table1 t3
       WHERE t3.TIMESTAMP < t1.TIMESTAMP)

输出

如你所见,我把一个法线改成开场也出现了。根据您的数据,我不知道您想如何处理这些数据。您是否需要为边境案件提供足够的信息,以便我们知道如何处理这些案件。

这可以解决添加另一个条件反转最后一个条件以确保关闭之前没有任何其他打开。

此代码仍然需要针对其他情况进行进一步测试。