mysql - 如何在自联接中编写随行的当前迭代而变化的条件
问题描述
一个表(测试)有一个描述
+-------+-------------+------+-----+---------+-------+
| 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
请参阅演示。
结果:
| 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
推荐阅读
- html - SVG 中的标题:如何让它看起来更快?
- docker - 如何更改在 Docker 上运行的 Db2 的密码?
- amazon-web-services - 使用无服务器框架定义 lambda 授权方响应格式
- jasper-reports - 在 JSS 报告的帮助下编译的报告不适用于 Java 代码 - 引发 ReportExpressionEvaluationData
- java - 在Java中将整数转换为百分比
- bbedit - 如何转到特定的字符偏移
- python - 编写一个程序,从三个文件中查询信息。程序应要求用户输入电话号码、打印姓名、ss 号码、年收入
- swift - 检查数组是否包含任何偶数,然后显示最低的偶数(如果没有偶数,则显示奇数)
- python - Emum没有赋值
- javascript - 从另一个页面 MERN 堆栈单击时执行操作