Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Анализация данных со счетчика / 12 сообщений из 12, страница 1 из 1
08.10.2002, 13:49:05
    #32056324
Максим
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Анализация данных со счетчика
Всем привет!
У меня есть счетчик, который считает кубы(кубические метры) проходящей через него жидкости, и число кубов записывается в таблицу (1,2,3,4,5,6,...,99).Запись в таблицу произходит каждую секунду, в связи с чем значения в этом поле повторяется (т.к. разход меньше, чем куб/сек).Предел счетчика 99, в связи с чем после 99 он сбрасывается на 0, и идет дальше по кругу. Так-же его могут сбросить в ручную, в связи с чем он опять начнет считать с 0. Мне надо посчитать количество кубов за единицу времени (к примеру за месяц). В связи с тем, что значения подряд будут повторяться, я предстявляю себе этот подсчет следующим образом : max(field1)-min(field1)(за определенный период времени), но ведь если будут нули, то этот временной интервал выборки надо бить еще на части, чтобы в каждом интервале выполнить вычисление (max(field1)-min(field1)), а потом сложить результаты. Каким образом можно отследить переходы через 0 и подсчитать сумму кубов за -месяц-?
Если есть другие идеи по решению данной задачи, то я буду рад, если Вы выскажите свое мнение!
Но а если есть предложения и советы по предложенному плану выполнения подсчета (как это можно реализавать), то я буду рад Вас выслушать!
Заранее благодарен всем, кто примет участие в обсуждении данной задачи!
...
Рейтинг: 0 / 0
08.10.2002, 14:15:36
    #32056333
dkstranger
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Анализация данных со счетчика
Надеюсь, что записи упорядочены
по времени (id)
Таким образом, нужно разбить
на интервалы, где знач счетчика=0

1. Создается стек /врем таблица/,
create table #stack(
zero_nom int,
pred_nom int,
pred_sum int)

Тудыть заносится первое знач, где 0

2. Расход по граница равен сумме pred_sum

3. Расход "за границей" равен расходу до
пред границе + тек знач счетчика
...
Рейтинг: 0 / 0
08.10.2002, 14:26:16
    #32056339
SergSuper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Анализация данных со счетчика
Собственно надо также посчитать сколько раз счетчик прошел через нуль. Т.е. когда время(или порядковый номер) увеличилось, у значение счетчика не выросло. Мне кажется что тогда решенее очевидно:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
declare @t table (id int identity, n int)
insert @t select  1  
union all select  2 
union all select  20 
union all select  2    -- * 100
 
union all select  3   
union all select  3    -- * 200   
 
union all select  7 
union all select  3    -- * 300
 
union all select  30 

select (select n from @t where id=(select max(id) from @t))-
       (select n from @t where id=(select min(id) from @t))+
       (select count(*) from @t t1, @t t2
          where t2.id=t1.id+ 1  and t2.n<=t1.n)* 100 

Если нет порядкового номера(id в данном случае), то будет несколько сложнее, но тоже реально - надо брать максимальное предыдущее время.
...
Рейтинг: 0 / 0
08.10.2002, 14:45:44
    #32056348
dkstranger
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Анализация данных со счетчика
2SuperSerg
насколько я понял, значение счетчика
может не достигать 100, а обнуляться посередине...
Так что, алгоритм придется малость переделать
...
Рейтинг: 0 / 0
08.10.2002, 14:56:31
    #32056356
Максим
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Анализация данных со счетчика
Да счетчик могут сбрасывать.
Спосибо за предложенный вариант, буду разбираться.
...
Рейтинг: 0 / 0
08.10.2002, 15:01:05
    #32056359
SergSuper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Анализация данных со счетчика
2 dkstranger
Прежде чем критиковать, то что я написал - хотя бы гляньте на это :)
...
Рейтинг: 0 / 0
08.10.2002, 15:05:57
    #32056362
dkstranger
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Анализация данных со счетчика
2SergSuper

Я не критикую :)
Привожу скрипт
select (select n from @t where id=(select max(id) from @t))-
(select n from @t where id=(select min(id) from @t))+
(select count(*) from @t t1, @t t2
where t2.id=t1.id+1 and t2.n<=t1.n)*100

Последний оператор умножения на 100 предполагает,
что значение счетчика =100, что не гарантируется :)
...
Рейтинг: 0 / 0
08.10.2002, 18:25:42
    #32056498
ivan999
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Анализация данных со счетчика
занимался я счетчиками когда-то давно...

есть двухпроходной вариант, очень простой в реализации

1)
на первом проходе в цикле обходишь все строки
и убираешь все неизменившиеся значения счетчика


то есть если было 10,
а в следующей по времени записи 11,
то в другую таблицу заносишь запись,
например 10.10.2002 - 11 литров

а если значение не изменилось, то ничего не заносишь

таким образом у тебя исходный массив уменьшается,
в нем остаются только значащие записи


2)
ну собственно вот и все,
расход в литрах за определенный промежуток времени
равен количеству записей за этот промежуток

count(*) сделать я думаю не проблема
...
Рейтинг: 0 / 0
09.10.2002, 09:50:42
    #32056614
SergSuper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Анализация данных со счетчика
2 dkstranger
Приношу глубокие извинения, я упустил что счетчик еще сбрасывается вручную. До меня это дошло только когда собрался ложится спать.

В этом случае надо добавить сумму значений, которые были сброшены. Если при сбрасывании гарантированно будет записано значение нуль, то надо просто просуммировать значения перед нулём. Если нет - тогда надо с любом случае иметь информацию, что счетчик скинут вручную.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
declare @t table (id int identity, n int)
insert @t select  97  
union all select  98 
union all select  99 
union all select  0    -- * 100
 
union all select  1   
union all select  1    -- 
 
union all select  2 
union all select  3    -- * 4
 
union all select  0 
union all select  2 

select (select n from @t where id=(select max(id) from @t))-
       (select n from @t where id=(select min(id) from @t))+
       (select sum(t1.n+ 1 ) from @t t1, @t t2
          where t2.id=t1.id+ 1  and t2.n= 0 )

Почему складываются t1.n +1 : дело в том что когда после 99 становится нуль, то это можно тоже назвать скидыванием счетчика и логично прибавлять не 99, а 100.
Метод ivan999 тоже довольно интересный, но подходит если только нет "дырок".
...
Рейтинг: 0 / 0
09.10.2002, 10:00:01
    #32056619
dkstranger
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Анализация данных со счетчика
2SergSuper
На самом деле мне понравилась Ваша реализация и я не
наезжал на ее алгоритм.
По-моему, эта схема существенно элегантнее
варианта с курсором /кстати, соответствует подходу
реляционных БД/.
А по поводу 100 - исправляется легко .
Действительно, два шага -
на первом определяются граничные точки и значения
/практически один в один ваш запрос/
на втором - собствеено сам расчет /две ветки -
до границы и от границы до требуемой точки/.
Вариант с выбором только изменяющихся значений,
конечно, тоже будет работать, но мне он нравится
существенно меньше /например, совершенно неппригоден, если счетчик за один цикл фиксирует несколько кубов/
А в целом - неплохая задачка.
Я бы ее дал своим аспирантам лет 5 назад
в курсе реляционных БД :)

Успехов,
Дмитрий
...
Рейтинг: 0 / 0
09.10.2002, 10:17:33
    #32056626
Garya
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Анализация данных со счетчика
1. Запоздалый комментарий к первому скрипту SergSuper. А я бы прибавлял 100 к следующему значению прежде чем вычесть из него предыдущее и от результата брал бы остаток от целочисленного деления на 100.

2. А как отличить сброс счетчика в результате его переполнения от сброса в результате нажатия кнопки? SergSuper в своем последнем решении весьма удачное предположение о том, что значение счетчика, равное нулю, скорее всего явилось результатом сброса вручную. Однако, есть довольно ощутимая вероятность, что нулевые значения счетичка были получены в результате сброса при его переполнении. Тогда, если предыдущее значение счетчика 80, а следующее - 0... Кто скажет, прошел ли счетчик 20 "щелчков", или кто-то нажал кнопку сразу на цифре 80? Я это все к тому, что если вы хотите точно знать "сколько вешать граммов", то нужен еще один сигнал (дополнительный бит в таблице), в котором записывается информация о ручном сбросе счетчика. Кроме того, при ручном сбросе счетчика должны фиксироваться его показания. Если эти требования выполнены не будут, вы будете получать только результаты, близкие к реальным с определенной (возможно, и весьма высокой) степенью вероятности, но все-таки не точные.
...
Рейтинг: 0 / 0
09.10.2002, 15:50:50
    #32056790
ivan999
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Анализация данных со счетчика
по поводу "дырок" в данных:
можно ведь не просто
записывать изменяющиеся значения,
но, раз уж имеем предыдущее и последующее значения счетчика,
записывать приращение счетчика,
а в случае сброса в ноль надо просто для себя решить,
было ли в таком случае приращение или не было
ведь если 99 -> 0, то литр откачался
а если 20 -> 0, то литр не откачался


первую итерацию с подготовкой данных
можно ведь не только курсором делать


а что касается подхода реляционных баз данных,
то подготовка данных перед использованием как раз в духе OLAP,
т.к. последующие запросы к данным существенно ускоряются,
да и логика их становится более удобоваримой
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Анализация данных со счетчика / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]