2

可以使用分析功能来折叠这些记录吗

ssid  start_time            end_time                op_code
65F   08/JAN/2013 14:18:33  08/JAN/2013 14:18:34    2
65F   08/JAN/2013 14:18:53  08/JAN/2013 14:18:54    2
65F   08/JAN/2013 14:18:55  08/JAN/2013 14:18:59    3
65F   08/JAN/2013 14:19:33  08/JAN/2013 14:19:34    2
65F   08/JAN/2013 14:19:53  08/JAN/2013 14:19:54    2
65F   08/JAN/2013 14:19:55  08/JAN/2013 14:19:59    3
72F   08/JAN/2013 14:20:55  08/JAN/2013 14:20:56    2
72F   08/JAN/2013 14:19:57  08/JAN/2013 14:19:59    2

对此

ssid  start_time            end_time              c_dt                 op_code
65F   08/JAN/2013 14:18:33  08/JAN/2013 14:18:54  08/JAN/2013 14:18:59   2
65F   08/JAN/2013 14:19:33  08/JAN/2013 14:19:54  08/JAN/2013 14:19:59   2
72F   08/JAN/2013 14:19:57  08/JAN/2013 14:20:56

或者我必须只在 for 循环中处理它。我在 Oracle 11gR2

如果下一个 op_code 为 2,则 end_time 成为下一条记录的 end_time,我们继续替换该记录的结束时间,直到具有 op_code 3 的相同 ssid 到达。当 op_code 3 的记录到达时,我们生成 c_dt,它是具有相同 ssid 但 op_code 3 的记录的结束时间。我们为下一条记录重新开始这个过程

如果我们没有为特定 ssid 找到 op_code 3 的记录,则 c_dt 将为空,但 end_time 将是具有相同 ssid 的下一条记录的 end_time。

希望我清楚这个棘手的逻辑

4

1 回答 1

2

我会第一个说这不漂亮,但它应该让你朝着正确的方向前进。

首先,创建一个 CTE,其中包含具有相应行号的所有记录。

其次,创建另一个 CTE,该 CTE 具有操作码不相同的下一条记录。

第三,创建另一个具有最小行号、最大行号和下一个行号(可能为空)的 CTE,并使用它来获取结果。

它很可能被简化,但这是我的第一次尝试。

WITH CTE AS (
  SELECT 
     t.ssid,t.start_time,t.end_time,t.op_code
    ,ROW_NUMBER() OVER (ORDER BY Start_Time) rn
  FROM YourTable t
) , 
CTE2 AS (
  SELECT C.SSID, C.RN, MIN(C2.RN) RN2
  FROM CTE C
    LEFT JOIN CTE C2 ON 
      C.RN < C2.RN AND 
      C.OP_CODE <> C2.OP_CODE AND 
      C.SSID = C2.SSID
  WHERE C.Op_Code = 2
  GROUP BY C.SSID, C.RN
) ,
CTE3 AS (
  SELECT SSID, MIN(RN) MinRN, MAX(RN) MaxRN, RN2 
  FROM CTE2
  GROUP BY SSID, RN2
) 
SELECT c.ssid, 
  c.start_time, 
  c3.end_time, 
  c4.end_time c_dt, 
  c.op_code
FROM CTE c
   JOIN CTE3 c2 ON c.RN = c2.MinRN
   JOIN CTE c3 ON c2.MaxRN = c3.RN
   LEFT JOIN CTE c4 ON c2.RN2 = c4.RN

这是SQL Fiddle

祝你好运。

于 2013-02-04T04:45:03.303 回答