行之间的日期差异

时间:2013-08-20 17:39:56

标签: sql oracle date-difference

我有以下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

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

这个想法是弄清楚交易在最终处理到状态“P”之前在各种状态中的持续时间。交易的生命周期按以下顺序 - > F - > W - > S - > P.其中F是第一个状态,P是最终状态。

有人可以帮忙吗?提前谢谢。

3 个答案:

答案 0 :(得分:2)

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

您的状态代码不会排序为F - > W - > S - > P,这就是下面的查询具有CASE函数LAG的大ORDER 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年的Jnauary 1,因为这就是Oracle(和ANSI)喜欢看日期常量的方式。当您使用1-jan-2008时,您依赖于Oracle的默认日期格式,这是一个可以更改的会话值。如果它被更改,您的查询将停止工作。

答案 1 :(得分: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

答案 2 :(得分:0)

了解oracle窗口分析。 http://www.orafaq.com/node/55

您需要对当前行日期和该日期的延迟进行差异处理。 希望有道理。