mysql - 如何在自连接中编写随行的当前迭代而变化的条件

标签 mysql sql

一个表(测试)有一个描述

+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| task  | varchar(2)  | NO   |     | NULL    |       |
| time  | int(11)     | NO   |     | NULL    |       |
| type  | char(1)     | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

并包含数据

+------+------+------+
| task | time | type |
+------+------+------+
| T1   |    1 | S    |
| T2   |    2 | S    |
| T1   |    7 | E    |
| T1   |    8 | S    |
| T1   |   14 | E    |
| T2   |   15 | E    |
| T1   |   16 | S    |
| T2   |   17 | S    |
| T3   |   20 | S    |
| T1   |   21 | E    |
| T3   |   25 | E    |
+------+------+------+

表示在某个时间单位开始(S)或完成(E)的任务的数据集。是否可以以输出包含任务开始时间和结束时间的表格的方式加入它。这里 (T2, 17, S) 在最终输出中被跳过,因为还没有关于它的结束时间的数据。

最终结果:-

+------+------+------+
| task | start| end  |
+------+------+------+
| T1   |    1 | 7    |
| T2   |    2 | 15   |
| T1   |    8 | 14   |
| T1   |   16 | 21   |
| T3   |   20 | 25   |
+------+------+------+

从最终结果可以看出,任务 T (T1) 的所有时间帧都是互斥的 [(1,7),(8,15),(16,25)]。

无法找出加入的条件规则

select S_table.task, S_table.time as start, E_table.time as end
from (select * from test where type='S') as S_table
left join (select * from test where type='E') as E_table
on
S_table.task = E_table.task
and
E_table.time should be greater than previous E_table.time for same task
and
E_table.time should be least within S_table.time < E_table.time
  • 在第一行的结果表中,所有 E_table.time (7,15,14,21,25) 都大于 S_table.time(正在查看的当前行,即 1),但 7 是因此选择的最少的

  • 在第二行的结果表中,所有 E_table.time 都大于前一个 (7),即 (15,14,21,25) 大于 2,但选择了至少一个,即 15

最佳答案

对于每个开始时间,您需要获取大于该开始时间的“E”类型的最小时间:

select t.* from (
  select 
    t.task,
    t.time start,
    (select min(time) from test where type = 'E' and task = t.task and time > t.time) end
  from test t 
  where t.type = 'S' 
) t
where t.end is not null

参见 demo .
结果:

| task | start | end |
| ---- | ----- | --- |
| T1   | 1     | 7   |
| T2   | 2     | 15  |
| T1   | 8     | 14  |
| T1   | 16    | 21  |
| T3   | 20    | 25  |

您可以像您的代码一样使用内部自联接获得相同的结果:

select S_table.task, S_table.time as start, E_table.time as end
from (select * from test where type='S') as S_table
inner join (select * from test where type='E') as E_table
on
S_table.task = E_table.task
and 
E_table.time = (
  select min(time) from test where type = 'E' and task = S_table.task and time > S_table.time
)
order by S_table.time

关于mysql - 如何在自连接中编写随行的当前迭代而变化的条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56156977/

相关文章:

sql - 无法指定数据类型 int 的列宽

MySQL:表 1 中的 SELECT 字段不存在于表 2 中

mysql - 用户向 mysql 提交内容并进行审核 : separate table?

php - 将两个 mysql 查询连接在一起

SQL - 在 XML.value() 中使用变量作为整个 XQuery 路径

mysql - 如何在gorm中串连?

mysql - Left Outer Join 对被加入者有条件

php - 外键 mysql 和 phpmyadmin

php - 从多个表中进行选择的最佳方法

mysql - 如何找到mysql varchar列的最大值