在 SQLite 表中查找重复项

问题描述 投票:0回答:1

我有一个表格,其中以一定的时间间隔收集来自传感器的数据(例如温度)。
其中一些数据很少更改,因此连续的行仅 ID 不同。
我希望能够找到这些行并删除重复项,只留下具有相同数据的最旧和最年轻的行。

目前我是这样做的:

SELECT
    m.statistic_id
  , c.id
FROM statistics_meta AS m
INNER JOIN statistics AS c ON c.metadata_id = m.id
INNER JOIN statistics AS p ON p.id = (SELECT MAX(t.id) FROM statistics AS t WHERE t.metadata_id = m.id AND t.id < c.id)
INNER JOIN statistics AS n ON n.id = (SELECT MIN(t.id) FROM statistics AS t WHERE t.metadata_id = m.id AND t.id > c.id)
WHERE IFNULL(c.state, 0) = IFNULL(p.state, 0)
  AND IFNULL(c.state, 0) = IFNULL(n.state, 0)

*

c
- 当前行,
p
- 上一行,
n
- 下一行

不幸的是,这个查询需要很长时间,并且随着新行的出现,它会花费更长的时间。
怎样才能做得更好?

sqlite home-assistant
1个回答
0
投票

你谈论了id和温度,但我发现你的SQL很难与这些数量联系起来,因为你有表

statistics
statistics_meta
以及各种列
id
statistic_id
metadata_id
state
,没有这些表和列的描述。请参阅提出良好的结构化查询语言 (SQL) 问题的提示。因此,我将解决一些我能理解的问题,也许您可以将其与您的问题联系起来:

假设您有一个表

measurement
,其中有两列:
id
temperature
,那么下面的SQL可能比您所实现的更高效;你必须尝试一下才能看到。这个想法是,如果您有一行包含一些
id
值 ID 和
temperature
值 T,那么如果前两行(即
id
值 ID-1 和 ID-2)具有相同的
temperature
值您可以安全地删除
id
值 ID-1 的行。因此,我们创建一个子查询来计算要删除的行,然后按如下方式执行删除:

/* create table */
create table measurement (
  id int primary key,
  temperature int
 );
 
/* create some sample data */
insert into measurement(id, temperature) values
    (1, 72),
    (2, 75),
    (3, 75),
    (4, 77),
    (5, 77),
    (6, 77),
    (7, 77),
    (8, 78),
    (9, 78),
    (10, 78),
    (11, 79)
;

/* delete the rows */
delete from measurement where id in (
    select id - 1 from measurement m
    where temperature = (select temperature from measurement where id = m.id - 1)
    and temperature = (select temperature from measurement where id = m.id -2)
);
 

/* redisplay table after deletion */
select * from measurement;

显示:

id    temperature
--    -----------
1     72
2     75
3     75
4     77
7     77
8     78
10    78
11    79
© www.soinside.com 2019 - 2024. All rights reserved.