Mysql 根据以前的记录有条件地计算数据的查询
如果标题描述不够,请原谅。 以下是我的问题场景: 我有一张桌子,上面有以下列: 时间列是包含日期/时间的varchar 我需要找出每个订单从一个状态过渡到另一个状态所需的时间-有效状态转换定义为:Mysql 根据以前的记录有条件地计算数据的查询,mysql,Mysql,如果标题描述不够,请原谅。 以下是我的问题场景: 我有一张桌子,上面有以下列: 时间列是包含日期/时间的varchar 我需要找出每个订单从一个状态过渡到另一个状态所需的时间-有效状态转换定义为: S->A MS->MA MS-M 也就是说,转换可以是从提交到确认、修改提交到修改确认或修改提交到修改 MS可以转换成MA,然后再转换成M,但我只对在这种情况下从MS到MA的转换感兴趣 在上述情况下: oid 1 transitioned from S to A. oid 2
S->A
MS->MA
MS-M
也就是说,转换可以是从提交到确认、修改提交到修改确认或修改提交到修改
MS可以转换成MA,然后再转换成M,但我只对在这种情况下从MS到MA的转换感兴趣
在上述情况下:
oid 1 transitioned from S to A.
oid 2 changed from S to A (rev 0)
oid 2 changed from MS to MA (rev 1) - here we don't want to consider transition to M
oid 2 changed from MS to M (rev 2)
因此,查询输出应如下所示,所用时间以毫秒为单位:
oid rev timeTaken state
1 0 (T3-T1) A
2 0 (T4-T2) A
2 1 (T6-T5) MA
2 2 (T9-T8) M
所以,若当前记录状态为MA或M,则仅当前一记录状态为MSASSUNG时,才需要计算时间差,这是按oid、rev、time排序的。如果当前记录状态为M,如果上一个记录状态为MA,则跳过
在mysql中使用sql查询是否可以做到这一点。任何指示都会有帮助。谢谢
====
该表将时间作为主键
我有这个查询,如果它有任何帮助的话,我会以正确的方式对它进行排序 按订单ID、时间、版本从订单中选择oid、版本、状态、时间 这将提供: oid旋转状态时间 10秒T1 10 A T3 20秒T2 20 A T4 2 1毫秒T5 2 1毫安T6 2.1米T7 2毫秒T8 2米T9
这会有帮助吗?嗯,我认为这应该用代码来完成,而不是用数据库 我可以想出一种用SQL实现这一点的方法,但它有点复杂。 事情是这样的。假设您的原始表是t1 创建一个视图,其中包含每个oid(修订版)中所有可能的转换
create view transitions as
select a.oid, a.rev, a.state as state_from, b.state as state_to,
a.time as time_from, b.time as time_to
from t1 as a, t1 as b
where a.oid=b.oid
and a.rev=b.rev
and a.time<b.time;
+------+------+------------+----------+-----------+---------+
| oid | rev | state_from | state_to | time_from | time_to |
+------+------+------------+----------+-----------+---------+
| 1 | 0 | S | A | T1 | T3 |
| 2 | 0 | S | A | T2 | T4 |
| 2 | 1 | MS | MA | T5 | T6 |
| 2 | 1 | MS | M | T5 | T7 |
| 2 | 1 | MA | M | T6 | T7 |
| 2 | 2 | MS | M | T8 | T9 |
+------+------+------------+----------+-----------+---------+
现在,您只需要选择您感兴趣的转换是从时间到状态以及状态到。您可以将此查询与前面的查询相结合,以便执行步骤2。这不是步骤2中唯一的新事物。最后一个和/或位是:
select a.oid,a.rev,a.state_to as state,a.time_to-a.time_from as timeTaken
from transitions as a
join (
select oid, rev, time_from, min(time_to) as time_to
from transitions
group by time_from
) as b
on a.oid=b.oid and a.rev=b.rev
and a.time_from=b.time_from and a.time_to=b.time_to
and ( (a.state_from='S' and a.state_to='A')
or (a.state_from='MS' and a.state_to='MA')
or (a.state_from='MS' and a.state_to='M')
);
+------+------+-------+-----------+
| oid | rev | state | timeTaken |
+------+------+-------+-----------+
| 1 | 0 | A | T3-T1 |
| 2 | 0 | A | T4-T2 |
| 2 | 2 | M | T6-T5 |
| 2 | 1 | MA | T9-T8 |
+------+------+-------+-----------+
总之,执行步骤1一次以创建视图,然后每次需要执行计算时执行步骤3
我敢打赌,有一种更有效的方法可以做到这一点——这不是我的专长。
我认为进行连接比将其全部移动到where子句便宜,创建视图只需一次性成本。问题,如果原始表具有某种自动递增id,这可能会容易得多。是吗?我们可以假设时间已排序吗?我使用此查询以正确的方式对其排序:抱歉,新手错误单击enter将更新原始输入区域我不是SQL专家,但我认为您要做的应该属于代码,而不是查询本身。
select a.*
from transitions as a
join (
select oid, rev, time_from, min(time_to) as time_to
from transitions
group by time_from
) as b
on a.oid=b.oid and a.rev=b.rev
and a.time_from=b.time_from and a.time_to=b.time_to;
+------+------+------------+----------+-----------+---------+
| oid | rev | state_from | state_to | time_from | time_to |
+------+------+------------+----------+-----------+---------+
| 1 | 0 | S | A | T1 | T3 |
| 2 | 0 | S | A | T2 | T4 |
| 2 | 1 | MS | MA | T5 | T6 |
| 2 | 1 | MA | M | T6 | T7 |
| 2 | 2 | MS | M | T8 | T9 |
+------+------+------------+----------+-----------+---------+
select a.oid,a.rev,a.state_to as state,a.time_to-a.time_from as timeTaken
from transitions as a
join (
select oid, rev, time_from, min(time_to) as time_to
from transitions
group by time_from
) as b
on a.oid=b.oid and a.rev=b.rev
and a.time_from=b.time_from and a.time_to=b.time_to
and ( (a.state_from='S' and a.state_to='A')
or (a.state_from='MS' and a.state_to='MA')
or (a.state_from='MS' and a.state_to='M')
);
+------+------+-------+-----------+
| oid | rev | state | timeTaken |
+------+------+-------+-----------+
| 1 | 0 | A | T3-T1 |
| 2 | 0 | A | T4-T2 |
| 2 | 2 | M | T6-T5 |
| 2 | 1 | MA | T9-T8 |
+------+------+-------+-----------+