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