0

我有以下 SQL 查询:

SELECT t.trans_id, t.business_process_id, tsp.status, tsp.timestamp
  FROM tran_stat_p tsp, tran t
 WHERE t.trans_id = tsp.trans_id
       AND tsp.timestamp BETWEEN '1-jan-2008' AND SYSDATE
       AND t.business_process_id = 'ABC01'

它输出如下数据:

trans_ID business_process_id status timestamp
14444400 ABC01 F 6/5/2008 12:37:36 PM
14444400 ABC01 W 6/6/2008 1:37:36 PM
14444400 ABC01 S 6/7/2008 2:37:36 PM
14444400 ABC01 P 6/8/2008 3:37:36 PM
14444401 ABC01 F 6/5/2008 12:37:36 PM
14444401 ABC01 W 6/6/2008 1:37:36 PM
14444401 ABC01 S 6/7/2008 2:37:36 PM
14444401 ABC01 P 6/8/2008 3:37:36 PM

除了上述之外,我想添加一个列,用于计算每个唯一的状态 W&F、S&W、P&S 之间的时间差(以天为单位)trans_id

这个想法是弄清楚交易在最终被处理为状态“P”之前处于各种状态的时间。事务的生命周期顺序如下 -> F -> W -> S -> P。其中 F 为第一个状态,P 为最终状态。

任何人都可以帮忙吗?提前致谢。

4

3 回答 3

2

实际查询将使用LAG,它将为您提供前一行的值。

您的状态代码不会排序为F-> W-> S-> ,这就是为什么下面的查询具有函数的PCASE语句的原因- 它将状态代码转换为遵循您的事务生命周期的值。LAGORDER BY

SELECT
  t.trans_id,
  t.business_process_id,
  tsp.status,
  tsp.timestamp,
  tsp.timestamp - LAG(timestamp) OVER (
    PARTITION BY tsp.trans_id
    ORDER BY
      CASE tsp.Status
        WHEN 'F' THEN 1
        WHEN 'W' THEN 2
        WHEN 'S' THEN 3
        WHEN 'P' THEN 4
        END) AS DaysBetween
FROM tran t
INNER JOIN tran_stat_p tsp ON t.trans_id = tsp.trans_id
WHERE tsp.timestamp BETWEEN DATE '2008-01-01' AND SYSDATE
  AND t.business_process_id = 'ABC01';

还有一些注意事项:

  • 该查询未经测试。如果您遇到问题,请发布一些示例数据,我会对其进行测试。
  • 我曾经DATE '2008-01-08'定义 2008 年 1 月 1 日,因为这就是 Oracle(和 ANSI)喜欢日期常量的方式。当您使用时,1-jan-2008您依赖于 Oracle 的默认日期格式,这是一个可以更改的会话值。如果更改了,您的查询将停止工作。
于 2013-08-20T18:20:46.163 回答
1

您可以使用LEAD检索下一个时间戳值并计算每个状态(F、W 和 S)中剩余的时间,并将TRUNC计算的天数作为整数:

SELECT t."trans_ID", t."business_process_id", tsp."status", tsp."timestamp", 
       LEAD("timestamp", 1) OVER (
                  PARTITION BY tsp."trans_ID" 
                  ORDER BY "timestamp") AS "next_timestamp",
       trunc(LEAD("timestamp", 1) OVER (
                        PARTITION BY tsp."trans_ID" 
                        ORDER BY "timestamp")) - trunc(tsp."timestamp") as "Days"
  FROM tran t
INNER JOIN tran_stat_p tsp ON t."trans_ID" = tsp."trans_ID" 
       AND tsp."timestamp" BETWEEN '01-jan-2008 12:00:00 AM' AND SYSDATE
WHERE t."business_process_id" = 'ABC01'

请参阅 SQLFIDDLE:http ://www.sqlfiddle.com/#!4/04633/49/0

于 2013-08-20T18:59:54.237 回答
0

查看 oracle 窗口分析。 http://www.orafaq.com/node/55

您需要对当前行日期和该日期的滞后进行比较。希望这是有道理的。

于 2013-08-20T17:44:26.147 回答