You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle SQL:基于时间差重置计数器并筛选指定记录

Oracle SQL 需求与实现方案

需求说明

需要在查询中新增计数器列,并筛选特定范围的数据:

  • 计数器列规则:根据UnixDateTime_Diff(上一行UnixDateTime - 当前行UnixDateTime)判断取值:
    • 当UnixDateTime_Diff < -100时,计数器值为1
    • 当UnixDateTime_Diff > -100时,计数器值为0
  • 最终仅保留最后一条计数器值为0的记录之后的所有数据

当前查询语句

with products as (
select * from (
select  distinct 
ID,
UnixDateTime,
OrderNumber,
to_date('1970-01-01','YYYY-MM-DD') + numtodsinterval(UnixDateTime,'SECOND')+ 1/24  as "Date_Time"
from DB
where
(date '1970-01-01' + UnixDateTime * interval '1' second) + interval '1' hour 
> sysdate - interval '2' day
)
),
prod_prev AS (
 SELECT p.*, 
        lag("Date_Time")over(order by "Date_Time" ASC) as Previous_Time,
        lag(UnixDateTime)over(order by "Date_Time" ASC) as UnixDateTime_Previous_Time, -- 原语句此处存在语法错误,已修正
        "Date_Time" - Previous_Time AS diff -- 原语句位置错误,已调整
   FROM products p    
), 
run_sum AS (
 SELECT p.*, "Date_Time"-Previous_Time as "Diff", UnixDateTime_Previous_Time-UnixDateTime AS "UnixDateTime_Diff"
   FROM prod_prev p    
)
SELECT * FROM run_sum
ORDER By UnixDateTime, "Date_Time" DESC

注:原prod_prev子查询存在语法错误,已在上述代码中修正

当前查询结果

IDUnixDateTimeOrderNumberDate_TimePrevious_TimediffUnixDateTime_Diff
1166261568810008-SEP-2022 06:41:28(null)(null)(null)
2166261575210008-SEP-2022 06:42:3208-SEP-2022 06:41:280.00074-64
3166261576510008-SEP-2022 06:42:4508-SEP-2022 06:42:320.000150-13
4166261585910008-SEP-2022 06:44:1908-SEP-2022 06:42:450.001088-128
5166261598710008-SEP-2022 06:46:2708-SEP-2022 06:44:190.00148-44
6166261603110008-SEP-2022 06:47:1108-SEP-2022 06:46:270.00051-36

解决方案

实现思路

  1. 新增计数器列:用CASE表达式根据UnixDateTime_Diff计算取值,首行无前置数据时默认设为0
  2. 定位分界点:找到最后一条计数器为0的记录的时间戳
  3. 筛选目标数据:保留所有晚于该分界点的记录

完整SQL语句

WITH products AS (
    SELECT DISTINCT
        ID,
        UnixDateTime,
        OrderNumber,
        TO_DATE('1970-01-01', 'YYYY-MM-DD') + NUMTODSINTERVAL(UnixDateTime, 'SECOND') + 1/24 AS "Date_Time"
    FROM DB
    WHERE
        (DATE '1970-01-01' + UnixDateTime * INTERVAL '1' SECOND) + INTERVAL '1' HOUR 
        > SYSDATE - INTERVAL '2' DAY
),
prod_prev AS (
    SELECT 
        p.*,
        LAG("Date_Time") OVER(ORDER BY "Date_Time" ASC) AS Previous_Time,
        LAG(UnixDateTime) OVER(ORDER BY "Date_Time" ASC) AS UnixDateTime_Previous_Time
    FROM products p
),
run_sum AS (
    SELECT 
        p.*,
        "Date_Time" - Previous_Time AS "Diff",
        UnixDateTime_Previous_Time - UnixDateTime AS "UnixDateTime_Diff",
        -- 新增计数器列
        CASE
            WHEN UnixDateTime_Previous_Time - UnixDateTime < -100 THEN 1
            ELSE 0
        END AS counter
    FROM prod_prev p
),
-- 获取最后一条counter=0的记录的时间戳
last_zero AS (
    SELECT MAX(UnixDateTime) AS last_zero_unix
    FROM run_sum
    WHERE counter = 0
)
-- 筛选目标数据
SELECT rs.*
FROM run_sum rs
CROSS JOIN last_zero lz
WHERE rs.UnixDateTime > lz.last_zero_unix
ORDER BY rs.UnixDateTime, rs."Date_Time" DESC;

结果说明

针对示例数据,最后一条counter=0的是ID=3(UnixDateTime=1662615765),筛选后返回ID=4、5、6的记录:

IDUnixDateTimeOrderNumberDate_TimePrevious_TimeDiffUnixDateTime_Diffcounter
4166261585910008-SEP-2022 06:44:1908-SEP-2022 06:42:450.001088-1281
5166261598710008-SEP-2022 06:46:2708-SEP-2022 06:44:190.00148-440
6166261603110008-SEP-2022 06:47:1108-SEP-2022 06:46:270.00051-360

若需包含最后一条counter=0的记录,将WHERE rs.UnixDateTime > lz.last_zero_unix改为>=即可


内容的提问来源于stack exchange,提问作者Jdbfkfo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 04:50:30