2015-07-23 5 views
1

У меня есть таблица sqlite с отметками времени в миллисекундах в качестве первичного ключа, каждая строка должна быть 1 секунда или 1000 друг от друга. Иногда мой регистратор данных гаснет, и в это время нет данных в таблице. Как найти пробелы с помощью инструкции SQL? Возможно, существует решение на основе курсора.Как найти пробел в таблице sqlite?

table = PVT 
TS 
1119636081000 
1119636082000 
1119636083000 
1119636084000 
1119636085000 
------gap------ 
1119636090000 
1119636091000 
+0

Вы можете сделать таблицу дельт между текущей строкой и предыдущую строку и искать значения больше 1000 – Robert

ответ

2

Это может сработать. Предполагая, что имя таблицы "tstamps",

select a.ts 
from tstamps a 
where not exists 
    (select b.ts 
    from tstamps b 
    where b.ts = a.ts+1000) 
and exists 
    (select c.ts 
    from tstamps c 
    where c.ts = a.ts+2000) 

Другой способ

select a.ts 
from tstamps a 
where not exists 
    (select b.ts 
    from tstamps b 
    where b.ts = a.ts+1000) 
and a.ts < 
    (select max(c.ts) 
    from tstamps c 
    ) 

Использование оператора MINUS. Я не уверен, какой из этих запросов имеет лучшую производительность.

select ts+1000 
from pvt 
where ts != (select max(ts) from pvt) 
minus 
select ts 
from pvt 
where ts != (select min(ts) from pvt) 
+0

Последний, использующий MINUS, работал для меня, я ДУМАЮ, за исключением того, что у sqlite нет оператора-минуса, поэтому я использовал исключение. Я проверил несколько из них, используя select ts from pvt, где ts между X и Y, и я вижу пробелы. Производительность на самом деле не вызывает беспокойства, так как я не буду часто выполнять этот запрос, но он занял 9 секунд на 1,8 миллиона строк. – user3749364

0

Что-то вроде этого (при условии, PVT.TS ваше имя столбца):

SELECT * FROM 'table' WHERE PVT.TS ISNULL; 

или

SELECT * FROM 'table' WHERE PVT.TS IS NULL; 

Если коллектор фактически ввод пустой запись может понадобиться

WHERE PVT.TS = '' 

или

where ifnull(some_column, '') = '' 
+0

Если есть пробел, ни одна строка не создается, PVT - это имя таблицы, а TS - столбец. – user3749364

+0

Ах, так что это не пустое поле, а разрыв в шаблоне. Я предполагаю, что они не всегда увеличиваются на 5000 каждый раз? – Skavenger0

0

На момент написания статьи SQLite не поддерживает оконные функции, такие как LAG(TS) OVER (ORDER BY TS ASC) ни LEAD() OVER, которые легко бы дать вам предыдущие и следующие TS значения, соответственно.

Таким образом, вы должны сделать это сами:

sqlite> .mode col 
sqlite> .width 14 14 14 
sqlite> SELECT PVT.TS AS measurement, 
        prev.TS AS prev, 
        next.TS AS next 
      FROM PVT 
     LEFT JOIN PVT next ON PVT.TS = (next.TS - 1000) 
     LEFT JOIN PVT prev ON PVT.TS = (prev.TS + 1000); 

Это даст вам что-то вроде этого (я использовал различные данные, как вы увидите):

-- measurement  prev   next  
    ------------- ------------- ------------- 
    1119636081000     1119636082000 -- gap (no previous at all) 
    1119636082000 1119636081000 1119636083000 
    1119636083000 1119636082000 1119636084000 
    1119636084000 1119636083000 1119636085000 
    1119636085000 1119636084000     -- gap (no next offset 1000) 
    1119636088000     1119636089000 -- gap (no previous offset 1000) 
    1119636089000 1119636088000     -- gap (no next at all) 

Вы всегда можете ограничьте этот запрос только этими записями WHERE prev.TS IS NULL OR next.TS is NULL.

+0

Этот запрос займет слишком много времени почти на 2 миллиона строк. – user3749364

0

Создать таблицу индикаторной по крайней мере 86400 строк (по одному в секунду на один день):

create table Tally(n integer primary key not null); 
insert into Tally(n) values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); 
insert into Tally(n) select null from tally n1 , tally n2, tally n3, tally n4, tally n5; 

Регистрация таблицы PVT на транспонированные записи в течение дня:

select 1119636081000 + tally.n*1000 as Expected, pvt.ts from tally left join pvt on pvt.ts = 1119636081000 + tally.n*1000 where tally.n <= 86400 limit 15; 

дан таблица Я заполняю ваши данные образца. Я получаю это как результат:

Expected  TS 
------------- ------------- 
1119636081000 1119636081000 
1119636082000 1119636082000 
1119636083000 1119636083000 
1119636084000 1119636084000 
1119636085000 1119636085000 
1119636086000 
1119636087000 
1119636088000 
1119636089000 
1119636090000 1119636090000 
1119636091000 1119636091000 
1119636092000 
1119636093000 
1119636094000 
1119636095000 

Если вы затем дополнительно подали r где PVT.TS имеет нулевое значение, вы должны получить недостающие значения:

select 1119636081000 + tally.n*1000 as Expected, pvt.ts from tally left join pvt on pvt.ts = 1119636081000 + tally.n*1000 where tally.n <= 86400 and PVT.ts is null limit 15; 

Expected  TS 
------------- ---------- 
1119636086000 
1119636087000 
1119636088000 
1119636089000 
1119636092000 
1119636093000 
1119636094000 
1119636095000 
1119636096000 
1119636097000 
1119636098000 
1119636099000 
1119636100000 
1119636101000 
1119636102000 

Примечания: Я использую предел 15, чтобы держать себя в здравом уме на консоли

Смежные вопросы