计算状态之间的状态和时间

时间:2016-11-04 18:30:11

标签: sql

我有一张桌子如下图所示。我有一个列跟踪应用程序和应用程序状态随时间的变化。我跟踪它在日期列中更改状态的时间。该表按应用程序和状态从最旧到最新的更改日期排序。

+--------+-----------+--------+------------------+
| app_id | status_id | row_no |       date       |
+--------+-----------+--------+------------------+
|      1 | a         |     10 | 2016-10-04 21:35 |
|      1 | b         |     11 | 2016-10-12 21:50 |
|      1 | c         |     12 | 2016-10-25 20:40 |
|      1 | d         |     13 | 2016-10-26 16:10 |
|      1 | e         |     14 | 2016-10-26 16:10 |
|      2 | a         |     20 | 2016-09-15 1:26  |
|      2 | c         |     21 | 2016-09-15 21:32 |
|      2 | d         |     22 | 2016-09-16 21:51 |
|      2 | e         |     23 | 2016-09-16 21:51 |
|      2 | f         |     24 | 2016-09-20 22:55 |
|      2 | g         |     25 | 2016-10-20 22:46 |
|      2 | g         |     26 | 2016-10-20 22:46 |
+--------+-----------+--------+------------------+

我正在努力确定应用程序在达到最终状态之前花费了多少时间。下面是我试图在Sql中构建的表的示例。对于我试图捕获下一个状态的每个状态。上一个状态列显示该行中的状态,而下一个状态显示该应用程序的下一行中的下一个状态。如果应用程序处于其最后状态,则下一个状态将标记为“最后”。接下来,我通过计算两个日期之间的小时差来计算状态之间的时间。如果您能告诉我如何在Sql中实现此功能,我将非常感激。提前谢谢。

+--------+-----------+--------+------------------+-----------------+-------------+--------------+
| app_id | status_id | row_no |       date       | previous status | next status | time between |
+--------+-----------+--------+------------------+-----------------+-------------+--------------+
|      1 | a         |     10 | 2016-10-04 21:35 | a               | b           | 192.2333333  |
|      1 | b         |     11 | 2016-10-12 21:50 | b               | c           | 334.8333333  |
|      1 | c         |     12 | 2016-10-25 20:40 | c               | d           | 43.48333333  |
|      1 | d         |     13 | 2016-10-26 16:10 | d               | e           | 0            |
|      1 | e         |     14 | 2016-10-26 16:10 | e               | Last        | Last         |
|      2 | a         |     20 | 2016-09-15 1:26  | a               | c           | 20.08333333  |
|      2 | c         |     21 | 2016-09-15 21:32 | c               | d           | 24.31666667  |
|      2 | d         |     22 | 2016-09-16 21:51 | d               | e           | 0            |
|      2 | e         |     23 | 2016-09-16 21:51 | e               | f           | 97.06666667  |
|      2 | f         |     24 | 2016-09-20 22:55 | f               | g           | 743.8333333  |
|      2 | g         |     25 | 2016-10-20 22:46 | g               | g           | 0            |
|      2 | g         |     26 | 2016-10-20 22:46 | g               | Last        | Last         |
+--------+-----------+--------+------------------+-----------------+-------------+--------------+

2 个答案:

答案 0 :(得分:1)

它有点混乱,但是如果你有一定数量的status_id,你可以尝试用"和#34;子句并在app_id结束时将它们连接在一起。然后制作一个决赛桌,计算A和B之间,B和C之间的步骤等。然而,这不会产生类似你制作的表格。但它应该得到所有的时间差异。

with A_table as (
select
app_id,
date A_status
where status_id = 'a'
)
, B_table (
select
app_id,
date B_status
where status_id = 'b'
)
--MORE STATUS TABLE HERE

, combined_table (
select
a.app_id,
a.A_status,
b.B_status,
--MORE STATUS DATES HERE
from A_table a
left outer join B_table b on a.app_id = b.app_id
--LEFT OUTER JOIN MORE STATUS TABLES ON A_TABLE HERE
--YOU'RE MAKING ONE TABLE WITH EACH APP_ID ON ONE ROW WITH ALL TIME STAMPS
)
select
*,
B_status - A_status A_B
--MORE TIME SUBTRACTIONS HERE
--SINCE YOU'VE OUTER JOINED ABOVE, YOU'LL HAVE COLUMNS FOR ALL POSSIBLE
--STATUS STEPS AND THOSE WHICH DIDN'T HAVE THAT STEP WILL BE NULL
from combined

它有点笨重但是有一定数量的状态步骤,应该完成工作。它并没有考虑到最后一步的步骤"虽然。我不知道那是多么重要。您始终可以编写一个case语句,查看下一步以查看它是否为null。你想要的东西可以通过循环实现,但我从未使用过那些。

另请注意,如果您有重复的app_id,status_id和日期行,就像示例表中的最后两行一样,您需要在with表格中对其进行排序,例如仅采取第一行排,或排名。

答案 1 :(得分:0)

使用Sql Lead和Lag功能,我们可以实现这一目标。这是查询:

选择app_id,状态为prev_status,日期为prev_date,引导(状态)结束(以app_id顺序按日期分区)为next_status,超前(日期)(按日期分区按app_id分区)为from_date from table