Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 行之间的日期差异_Sql_Oracle_Date Difference - Fatal编程技术网

Sql 行之间的日期差异

Sql 行之间的日期差异,sql,oracle,date-difference,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' 它输出如下

我有以下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'
它输出如下数据:

交易ID
业务流程ID
状态
时间戳

14444400
ABC01
F
<6/5/2008 12:37:36
14444400
ABC01
<6/6/6/2008 1:37:36
14444400
ABC01
<6/7/2008 2:37:36
14444400
ABC01
P
<6/8/2008 3:37:36
14444401
ABC01
F
<6/5/2008 12:37:36
14444401
ABC01
W
<6/6/2008 1:37:36
14444401
ABC01
S
<6/7/2008 2:37:36
14444401
ABC01
P
<6/8/2008 3:37:36

除上述内容外,我还想添加一列,用于计算每个唯一的
trans\u id
状态W&F、S&W、p&S之间的时差(以天为单位)

这样做的目的是要计算出在最终处理到状态“p”之前,事务在各种状态下处于多长时间。事务的生命周期顺序为->F->W->S->P,其中F为第一状态,P为最终状态


有人能帮忙吗?提前感谢。

查看oracle window analytics。

您需要对当前行日期和该日期的延迟进行区分。
希望这是有道理的

查看oracle窗口分析。

您需要对当前行日期和该日期的延迟进行区分。
希望这是有道理的

实际查询将使用,这将为您提供前一行中的值

您的状态代码不会按
F
->
W
->
S
->
p
排序,这就是为什么下面的查询中有
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';
还有几个注意事项:

  • 该查询未经测试。如果你有问题,请张贴一些样本数据,我会测试它
  • 我使用日期“2008-01-08”
来定义jnauary12008,因为Oracle(和ANSI)喜欢日期常量的外观。当您使用
1-jan-2008
时,您依赖于Oracle的默认日期格式,这是一个可以更改的会话值。如果更改了,您的查询将停止工作
    实际查询将使用,这将为您提供前一行中的值

    您的状态代码不会按
    F
    ->
    W
    ->
    S
    ->
    p
    排序,这就是为什么下面的查询中有
    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';
    
    还有几个注意事项:

    • 该查询未经测试。如果你有问题,请张贴一些样本数据,我会测试它
    • 我使用日期“2008-01-08”
来定义jnauary12008,因为Oracle(和ANSI)喜欢日期常量的外观。当您使用
1-jan-2008
时,您依赖于Oracle的默认日期格式,这是一个可以更改的会话值。如果更改了,您的查询将停止工作
您可以使用
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'

请参阅SQLFIDLE:

您可以使用
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:

然后不要依赖Oracle的默认日期格式,只需使用TO_date()函数:例如,在TO_date('2001-JAN-01','YYYY-MON-DD')和SYSDATE之间。TO_date是一个有效的选择。我更喜欢这种方法,因为除其他外,它的输入更少:)当我运行查询时,我会得到中间日期的负值。如果我们按照上述顺序计算状态的差异,那么状态“F”和“P”不应该有一个空值吗?如果从F到P状态总是平稳的进行,那么之间的