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

如何从Home Assistant IoT设备历史数据结果集中删除每隔n行的数据?

需求说明

我有来自Home Assistant物联网设备的状态数据,这些数据会根据设备不同每日被多次记录,数据保留1年。需要对记录频繁的设备做如下数据清理:

  • 保留最近1个月的所有状态变更数据
  • 对超过1个月的数据,删除其中每隔一行(即保留一行、删除一行循环)

数据库数据摘录

state_identity_idlast_updated
2342932sensor.climate_outside_humidity2022-11-12 04:13:46.598786
2063613sensor.climate_outside_humidity2022-10-28 03:02:47.756064
1984952sensor.climate_outside_temperature2022-10-20 07:32:51.674016
925115sensor.climate_outside_humidity2022-07-25 09:54:01.095297
1897854sensor.climate_outside_humidity2022-10-11 17:28:13.448728
2005628sensor.climate_outside_temperature2022-10-22 12:37:21.027465
1071454sensor.climate_outside_humidity2022-08-04 13:16:02.885636
1663793sensor.climate_outside_temperature2022-09-17 14:36:05.900979
1756081sensor.climate_outside_temperature2022-09-27 23:17:25.688069
2372362sensor.climate_outside_temperature2022-11-14 02:28:16.034873

当前查询语句

SELECT state_id, entity_id, last_updated
FROM "states"
WHERE entity_id IN ("sensor.climate_outside_temperature","sensor.climate_outside_humidity")
AND last_updated < date('now', '-30 day')
ORDER BY entity_id,state_id DESC

解决方案

要实现按设备分组后对历史数据隔行删除,需要用窗口函数为每个设备组内的行生成序号,再筛选出要删除的行。

1. 先查询确认要删除的行

执行以下语句查看待删除的目标数据,确保符合预期:

WITH ranked_states AS (
  SELECT 
    state_id,
    entity_id,
    ROW_NUMBER() OVER (PARTITION BY entity_id ORDER BY state_id DESC) AS row_num
  FROM "states"
  WHERE 
    entity_id IN ('sensor.climate_outside_temperature','sensor.climate_outside_humidity')
    AND last_updated < date('now', '-30 day')
)
SELECT state_id, entity_id, row_num
FROM ranked_states
WHERE row_num % 2 = 0; -- 此处筛选偶数行删除,若要删奇数行改为row_num % 2 = 1

2. 执行删除操作

确认无误后,执行删除语句:

WITH ranked_states AS (
  SELECT 
    state_id,
    ROW_NUMBER() OVER (PARTITION BY entity_id ORDER BY state_id DESC) AS row_num
  FROM "states"
  WHERE 
    entity_id IN ('sensor.climate_outside_temperature','sensor.climate_outside_humidity')
    AND last_updated < date('now', '-30 day')
)
DELETE FROM "states"
WHERE state_id IN (SELECT state_id FROM ranked_states WHERE row_num % 2 = 0);

关键说明

  • ROW_NUMBER()窗口函数会按entity_id分组,每个组内按state_id降序(和你原查询的排序逻辑一致)生成连续行号
  • 通过行号取模(% 2)实现隔行筛选,你可以根据需求调整取模条件
  • 执行删除前务必先用SELECT语句验证,避免误删数据
  • Home Assistant使用的SQLite支持CTE(公共表表达式),上述语句可直接运行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 02:20:54