Ранее на этой неделе я задаю вопрос о последовательной фильтрации повторяющихся значений во время выполнения. Было несколько хороших ответов, но объем данных, которые я просматривал, был слишком медленным и невозможным.
В настоящее время в нашей базе данных значения событий не фильтруются. Результатом являются повторяющиеся значения данных (с разными отметками времени). Нам необходимо обрабатывать эти данные во время выполнения, а на уровне базы данных это требует больших затрат времени (и не может втягивать их в код, потому что они много используются в хранимых процессах), что приводит к увеличению времени выполнения запросов. Нам нужна структура данных, которую мы можем запросить, чтобы это хранилище данных было отфильтровано, чтобы во время выполнения не требовалась дополнительная фильтрация.
В настоящее время в нашей БД
То, что нам нужно
Это кажется тривиальным, но наша проблема в том, что мы получаем эти данные с беспроводных устройств, что приводит к несоответствию последовательности пакетов, а наш шлюз является многопоточным, поэтому мы не можем гарантировать, что получаемые нами значения в порядке. Что-то может появиться, например, «1» для 4 секунд назад и «0» для 2 секунд назад, но мы уже обрабатываем «1», потому что оно было первым. Мы кружили головы над тем, как это реализовать. Мы не можем сравнивать данные с последним значением в базе данных, потому что последнее, возможно, еще не поступило, поэтому, если бы мы выбросили эти данные, мы ошиблись бы, и наша последовательность могла бы полностью нарушиться. Итак, в настоящее время мы сохраняем каждое входящее значение, и база данных перемещается по времени в зависимости от времени .. но единицы могут отправлять 1,1,1,0 и его действительное значение, потому что событие все еще активно, но мы хотим сохранить только состояние включения и выключения (первое появление состояния включения 1,0,1,0,1,0). мы думали о триггере, но нам пришлось бы перетасовать данные каждый раз, когда приходило новое значение, потому что это может быть раньше, чем последнее сообщение, и это может изменить всю последовательность (вставка будет медленной).
Есть идеи?
Спросите, нужна ли вам дополнительная информация.
[EDIT] PK Не работает - проблема в том, что наши устройства на самом деле отправляют разные временные метки. поэтому ПК не будет работать, потому что 1,1,1 одинаковы ... но есть разные отметки времени. Подобное событие произошло в time1, событие все еще продолжается в time2, оно отправляет нам оба ... одно и то же значение в разное время.
Ms SQl - хочу удалить третью строку, потому что у нее такое же значение, как и у второй .. все, что я хочу, это первый экземпляр значения (на основе временной метки), все, что я хочу сохранить, это полный цикл события .. on, выкл, вкл, выкл. с проблемами, которые я упомянул об обработке вне очереди


Если я правильно понимаю, то, что вы хотите сделать, это просто не допустить попадания дубликатов в базу данных. Если это так, почему бы не определить PK (или уникальный индекс) для первых двух столбцов и не позволить базе данных сделать тяжелую работу за вас. Вставки Dupe не будут работать в зависимости от PK или AK, которые вы определили. Ваш код (или сохраненная процедура) тогда просто должен будет изящно обработать это исключение.
Вот решение для обновления. Производительность будет зависеть от индексов.
DECLARE @MyTable TABLE
(
DeviceName varchar(100),
EventTime DateTime,
OnOff int,
GoodForRead int
)
INSERT INTO @MyTable(DeviceName, OnOff, EventTime)
SELECT 'F07331E4-26EC-41B6-BEC5-002AACA58337', 1, '2008-05-08 04:03:47.000'
INSERT INTO @MyTable(DeviceName, OnOff, EventTime)
SELECT 'F07331E4-26EC-41B6-BEC5-002AACA58337', 0, '2008-05-08 10:02:08.000'
INSERT INTO @MyTable(DeviceName, OnOff, EventTime)
SELECT 'F07331E4-26EC-41B6-BEC5-002AACA58337', 0, '2008-05-09 10:03:24.000'
INSERT INTO @MyTable(DeviceName, OnOff, EventTime)
SELECT 'F07331E4-26EC-41B6-BEC5-002AACA58337', 1, '2008-05-10 04:05:05.000'
UPDATE mt
SET GoodForRead =
CASE
(SELECT top 1 OnOff
FROM @MyTable mt2
WHERE mt2.DeviceName = mt.DeviceName
and mt2.EventTime < mt.EventTime
ORDER BY mt2.EventTime desc
)
WHEN null THEN 1
WHEN mt.OnOff THEN 0
ELSE 1
END
FROM @MyTable mt
-- Limit the update to recent data
--WHERE EventTime >= DateAdd(dd, -1, GetDate())
SELECT *
FROM @MyTable
Нетрудно представить решение для фильтрации, основанное на этом. Это просто зависит от того, как часто вы хотите искать предыдущую запись для каждой записи (каждый запрос или время от времени).
Кроме того, мне непонятно, почему именно третью строку в вашем примере вы хотите удалить или не загружать.