Задавайте вопросы, мы ответим
Вы не зашли.
Приветствую!
есть таблица, в которой хранится данные и время когда они были записаны - интервал 1 секунда
|timestamp|float|
1 сек 356.0
2 сек 53.0
3 сек 5.9
4 сек 13.0
5 сек 200.0
6 сек 10.0
7 сек 36.2
8 сек 0.0
9 сек 3.0
10 сек 145.98
мне нужно сделать выборку для построения графика... если шаг сетки графика будет 1 секунда то я просто все подряд и строю график
но как быть если мне нужно сделать шаг сетки в 5 сек.. по идее мне нужно найти среднее значение первых 5ти секунд.. вторых 5ти секунд и т.д.
реально ли это сделать при помощи SQL?
но может быть и так что за некоторые секунды данные не были записаны и тогда таблица будет выглядеть к примеру
|timestamp|float|
1 сек 356.0
2 сек 53.0
3 сек 5.9
-------------------
8 сек 0.0
9 сек 3.0
10 сек 145.98
получается пр шаге в 5 секунд я возьму для первой точки графика 1.2.3 секунды... для второй точки графика 8.9.10 секунды
Неактивен
позволь поинтересоваться, на чём выборка и кому и в каком виде передаётся? Это сделать реально, например, с помощью хранимой процедуры, но если выборка небольшая (положим, 5000 точек), то можно и в проге (на js, php, java) добавить нужные точки. Всё зависит от того, в каком виде это должно быть, какие накладные расходы и пр.
Это во-первых, а во-вторых, если ты привёл реальные цифры, то это бида! Проведи анализ маломальский, у тебя от секунды к секунде так показания меняются, что никакая аппроксимация не поможет.
Отредактированно megamanx (12.08.2011 23:31:11)
Неактивен
вот пример данных
weight timestamp
251.594 2011-08-08 21:19:34
258.08 2011-08-08 21:19:35
254.274 2011-08-08 21:19:36
255.491 2011-08-08 21:19:37
256.379 2011-08-08 21:19:38
250.306 2011-08-08 21:19:39
250 2011-08-08 21:19:40
250 2011-08-08 21:19:41
250.229 2011-08-08 21:19:42
250 2011-08-08 21:19:43
254.012 2011-08-08 21:19:44
253.397 2011-08-08 21:19:45
250.848 2011-08-08 21:19:46
250 2011-08-08 21:19:47
250 2011-08-08 21:19:48
257.622 2011-08-08 21:19:49
261.519 2011-08-08 21:19:50
254.022 2011-08-08 21:19:51
250 2011-08-08 21:19:52
256.595 2011-08-08 21:19:53
253.37 2011-08-08 21:19:54
254.703 2011-08-08 21:19:55
254.428 2011-08-08 21:19:56
данные из MySQL будут использоваться в программе написанной на Java но хотелось бы реализовать это запросом - не делать несколько запросов из программы.
Отредактированно sniks (12.08.2011 23:41:49)
Неактивен
вот допустим варианты построения отчета имея эти данные....
1. по секундный отчет за 5 минут
2. по минутный отчет за час
3. по часовой отчет за 24 часа
буду очень признателен если поможете разобраться с данным вопросом
Неактивен
1 что пришло в голову - переложить во временную таблицу, а из неё уже делать выборку, примерно так
-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$
drop procedure if exists get_nums$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `get_nums`()
begin
declare done int default 0;
declare s1 int;
declare s2 int;
declare v1 float;
declare v2 float;
declare f int;
declare a int;
declare dif float;
declare c2 cursor for select times, num from times limit 1;
declare c1 cursor for select times, num from times limit 1,100000;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
drop table if exists temp_vals;
create table temp_vals(
times int,
num float);
open c2;
fetch c2 into s1, v1;
close c2;
open c1;
repeat
fetch c1 into s2, v2;
set f = s2 - s1;
if f=1 then
insert into temp_vals(times, num) values (s1, v1);
else
insert into temp_vals(times, num) values (s1, v1);
set a = 1;
set dif = (v2 - v1)/f;
set f = f-1;
sloop: loop
insert into temp_vals(times, num) values (s1+a, v1+(a*dif));
if a >= f then
leave sloop;
end if;
set a = a+1;
end loop sloop;
end if;
set s1 = s2;
set v1 = v2;
until done end repeat;
close c1;
end
Здесь из таблицы times(times int, num float) переваливаю в temp_times(times int, num float) с линейной аппроксимацией. Но это очевидно затратный подход.
В чём проблема на стороне сервера обрабатывать такие небольшие объёмы данных?- без разницы, что resultSet.next() вернёт, если разница между секундами != 1, достройте в массив. Я лично так делаю и не заморачиваюсь с выборкой.
2. Если не критично, просто засуньте нужные значения в текущую же таблицу, а не в новую. Если таблица мелкая, то на ней и индекс создавать затратно, и order by будет работать быстро.
3. посидим, подумаем, может, кто-то что-то дельное скажет.
Неактивен
sniks написал:
данные из MySQL будут использоваться в программе написанной на Java но хотелось бы реализовать это запросом - не делать несколько запросов из программы.
Из любви к искусству можно сделать и одним запросом. См http://sqlinfo.ru/forum/viewtopic.php?pid=26495#p26495
Но это будет сортировка нужного куска данных, временная таблица, группировка по ней. Несколько запросов из программы будут проще, тем более, что построение отчетов операция нечастая - смысла изгаляться нет.
Неактивен
из программы? а если у меня будет база за год? и отчет будет за 30-100 дней.. мне 30-100 запросов делать?
Неактивен
А в чём проблема-то на java написать? будет база за год, и что? Ведь нет необходимости хранить весь массив значений, нужно временно выделять память только под пустые куски. Курсор вернул несоответствие - посчитали в массив, курсор вернул два идущих подряд значение - берёте данные из базы и т.д.
Неактивен
так. буду пробовать. большое спасибо
Неактивен
try{
rs = st.executeQuery(sql);
rs.next();
float v2;
int s2;
int s1 = rs.getInt(1);
float v1 = rs.getFloat(2);
System.out.println(String.valueOf(s1)+" ^-> " + String.valueOf(v1));
float diff = 0;
int td = 0;
while (rs.next()){
s2 = rs.getInt(1);
v2 = rs.getFloat(2);
td = s2 - s1;
if (td == 1){
System.out.println(String.valueOf(s2)+" @-> " + String.valueOf(v2));
} else{
diff = (v2-v1)/(float)td;
for (int i=1; i<td; i++){
System.out.println(String.valueOf(s1+i) + " !-> " + String.valueOf(v1+i*diff));
}
System.out.println(String.valueOf(s2) + " -> " + String.valueOf(v2));
}
s1 = s2;
v1 = v2;
}
}catch(Exception e){};
Неактивен
Спасибо) за код но в Java проблем нет... затруднения были в SQL с формированием одного запроса под отчет. Но все равно спасибо!
Неактивен