可以使用分析功能来折叠这些记录 从这个
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的记录的end_time。 我们将为下一条记录重新开始此过程
如果我们没有为特定的ssid找到带有op_code 3的记录,那么c_dt将为null 但是end_time将是具有相同ssid的下一条记录的end_time。
希望我对这个棘手的逻辑很清楚
答案 0 :(得分:2)
我会第一个说这不是很好,但它应该让你朝着正确的方向前进。
首先,创建一个CTE,其中包含具有相应行号的所有记录。
其次,创建另一个CTE,它具有op代码不同的下一条记录。
第三,创建另一个具有最小行号,最大行号和下一行号(可能为空)的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。
祝你好运。