用数据库的功能,你这个要判断太多连续的数据了。层次坐标也不好弄。
上面要用下面的数据,下面又要用上面的数据,不好弄
WITH your_data AS (
SELECT 'A' AS 类别, TO_TIMESTAMP('2025-10-19 00:00:00', 'YYYY-MM-DD HH24:MI:SS') AS 时间, 100.00 AS 数值 FROM DUAL UNION ALL
SELECT 'A', TO_TIMESTAMP('2025-10-19 01:00:00', 'YYYY-MM-DD HH24:MI:SS'), 150.00 FROM DUAL UNION ALL
SELECT 'A', TO_TIMESTAMP('2025-10-19 02:00:00', 'YYYY-MM-DD HH24:MI:SS'), 20.00 FROM DUAL UNION ALL
SELECT 'A', TO_TIMESTAMP('2025-10-19 03:00:00', 'YYYY-MM-DD HH24:MI:SS'), 220.00 FROM DUAL UNION ALL
SELECT 'A', TO_TIMESTAMP('2025-10-19 04:00:00', 'YYYY-MM-DD HH24:MI:SS'), 100.00 FROM DUAL UNION ALL
SELECT 'A', TO_TIMESTAMP('2025-10-19 05:00:00', 'YYYY-MM-DD HH24:MI:SS'), 140.00 FROM DUAL UNION ALL
SELECT 'A', TO_TIMESTAMP('2025-10-19 06:00:00', 'YYYY-MM-DD HH24:MI:SS'), 10.00 FROM DUAL UNION ALL
SELECT 'A', TO_TIMESTAMP('2025-10-19 07:00:00', 'YYYY-MM-DD HH24:MI:SS'), 210.00 FROM DUAL UNION ALL
SELECT 'A', TO_TIMESTAMP('2025-10-19 08:00:00', 'YYYY-MM-DD HH24:MI:SS'), 20.00 FROM DUAL UNION ALL
SELECT 'A', TO_TIMESTAMP('2025-10-19 09:00:00', 'YYYY-MM-DD HH24:MI:SS'), 240.00 FROM DUAL UNION ALL
SELECT 'A', TO_TIMESTAMP('2025-10-19 10:00:00', 'YYYY-MM-DD HH24:MI:SS'), 100.00 FROM DUAL UNION ALL
SELECT 'A', TO_TIMESTAMP('2025-10-19 11:00:00', 'YYYY-MM-DD HH24:MI:SS'), 120.00 FROM DUAL UNION ALL
SELECT 'A', TO_TIMESTAMP('2025-10-19 12:00:00', 'YYYY-MM-DD HH24:MI:SS'), 140.00 FROM DUAL
),
t AS (
SELECT 类别, 时间, 数值,
CASE WHEN 数值 BETWEEN 100 AND 200 THEN 0 ELSE 1 END AS is_abnormal
FROM your_data
),
grouped AS (
SELECT 类别, 时间, 数值, is_abnormal,
ROW_NUMBER() OVER (PARTITION BY 类别 ORDER BY 时间) -
ROW_NUMBER() OVER (PARTITION BY 类别, is_abnormal ORDER BY 时间) AS grp
FROM t
),
avg_abnormal AS (
SELECT 类别, 时间, 数值, is_abnormal, grp,
AVG(数值) OVER (PARTITION BY 类别, is_abnormal, grp) AS avg_val
FROM grouped
)
SELECT
类别,
时间,
数值,
CASE
WHEN is_abnormal = 0 THEN 数值
ELSE avg_val
END AS 结果
FROM avg_abnormal
ORDER BY 类别, 时间
必须要排序
