如何在排序列表中关联不连续的数据?

时间:2015-03-16 19:18:11

标签: sql oracle

我有一张表和下面的数据。在该表中,' TIME'列显示插入数据的时间。 NODE_ENTER表示节点开始或结束。当它等于1时,表示节点已启动,开始时间为app_date和app_time。当NODE_ENTER为0时,表示节点已结束,现在,app_date和app_time显示结束时间。

对于此表,我希望在每个节点上获得总时间(对于起始节点,region_node,某处和sub_region节点)。但是我怎样才能正确地做到这一点?

ID     TIME         REFID   NODE      NODE_ENTER    APP_DATE    APP_TIME
12345   0           10150   start       1           20130605    94601
23456   3,7093E+11  10150   start       0           20130611    90115
56789   3,7093E+11  10150   region      1           20130611    90116
67891   3,72167E+11 10150   sub-region  1           20130625    162419
23432   3,72171E+11 10150   sub-region  0           20130625    173226
87656   3,72171E+11 10150   region      0           20130625    173227
34599   3,72171E+11 10150   somewhere   1           20130625    173227
87654   3,72237E+11 10150   somewhere   0           20130626    120121
66789   3,72237E+11 10150   region      1           20130626    120122
99891   3,72167E+11 10150   sub-region  1           20130627    104537
21132   3,72346E+11 10150   sub-region  0           20130627    181136
82356   3,79515E+11 10150   region      0           20130628    162656

我使用了LAG函数,如下所示,但我无法在两个连续和相同的命名行之间获得时间差。例如,区域节点不是连续的,因为子区域必须位于两个区域节点之间。现在我可以在两个起始节点或两个子区域节点之间获得时间差,但是如何在两个区域节点之间获得时间差?当我尝试在节点名称上使用LAG功能时,它不能再次工作,因为我可以拥有相同的节点名称。区域节点可以在某个节点之后启动并再次结束。

LAG(P.NODE, 1, '-') OVER(ORDER BY P.REFID,p.time) AS PREV_NODE,
LAG(P.APP_DATE, 1, '-') OVER(ORDER BY P.REFID,p.time) AS START_DATE,
LAG(P.APP_TIME, 1, '000000') OVER(ORDER BY P.REFID, p.time) AS START_TIME

1 个答案:

答案 0 :(得分:1)

我认为您希望REFIDNODE上的分区,而APP_DATEAPP_TIME上的订购

SELECT ref_id, node, node_enter, app_date, app_time
     , last_node_enter, last_app_date, last_app_time
  FROM (
    SELECT p.ref_id, p.node, p.node_enter, p.app_date, p.app_time
         , LAG(p.node_enter) OVER ( PARTITION BY p.ref_id, p.node ORDER BY p.app_date, p.app_time) AS last_node_enter
         , LAG(p.app_date) OVER ( PARTITION BY p.ref_id, p.node ORDER BY p.app_date, p.app_time) AS last_app_date
         , LAG(p.app_time) OVER ( PARTITION BY p.ref_id, p.node ORDER BY p.app_date, p.app_time) AS last_app_time
      FROM mytable p
) WHERE node_enter = 1 AND last_node_enter = 0;

我建议您将日期和时间存储为DATETIMESTAMP而不是NUMBERVARCHAR2