Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Посоветуйте как избавиться от запроса в цикле? :)  [new]
DASTAD
Member

Откуда:
Сообщений: 55
Прошу помощи.
SQL 2005
Имею в базе 2 таблички
первая: Parameters (PTime: datetime, Pvalue: float, ...) - в ней хранятся некие параметры объекта
вторая: Events (ETime: dateTime, Evalue: float, ...) - в ней хранятся описание событий

например,
объект - печь
Pvalue - температура
Evalue - количество угля(тонны), загруженного в печь
Обще описание работы.
Начало отсчета 06: 00, температура в печи 20 градусов, фиксируем в Parameters ('06:00:00', 22 )
в 06: 15 в печь закинули 2 тонны угля, сделали запись в Events ('06:15', 2 )
в 06: 30 в печь закинули еще 1,5 тонны - запись Events('06:30', 1.5)
в 06: 35 температура поднялась до 1000 - делаем запись в Parametrs ('06:35', 1000)
и т.д

Нужно из этих 2х таблиц сформировать отчет, вида
Report (PTime, PValue, Sum(Evalue)) за выбранных отрезок времени (T1, T2)

Пока на скорую руку сделал в лоб :)
Из программы делаю запрос к Parameters, (select Ptime, Pvalue from Parmeters where Ptime>T1 and Ptime<=T2 order by Ptime)
В цикле считываю время в Ptime(i) и Ptime(i+1) в i и i+1 записях
Делаю запросы к Events вида (Select sum(Evalue) from Events where Etime>Pvalue(i) and Etime<=Pvalue(i+1))
Пихаю результаты в отчет
Итог: таблицы бооооольшие, запросов много, работает меееееедленно :(


Подскажите как можно сформировать отчет одним запросом. Либо еще возможные варианты решения
Заранее благодарен.
8 сен 11, 07:00    [11244902]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте как избавиться от запроса в цикле? :)  [new]
ё
Guest
так как-то
select a.Pvalue_st, a.st, a.Pvalue_fn, a.fn, sum(b.Evalue) as xz
from

(select Pvalue as Pvalue_st, Ptime as st, c.Ptime as fn, c.Pvalue as Pvalue_fn 
from Parmeters p1 
cross apply (select top 1 Ptime, Pvalue from Parmeters p2 where p1.Ptime<p2.Ptime order by p2.Ptime) c
where Ptime>=T1 and Ptime<T2) a

inner join Events b
  on b.ETime between a.st and a.fn

group by a.Pvalue_st, a.st, a.Pvalue_fn, a.fn
а вообще, странно что в Events не предусмотренна явная связь с Parmeters ...
8 сен 11, 08:11    [11244944]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте как избавиться от запроса в цикле? :)  [new]
DASTAD
Member

Откуда:
Сообщений: 55
спасибо, не сталкивался раньше с cross aplly

но насколько я понял из его описания, это что то вызова процедуры для каждой строки таблицы...
то есть будет тот же цикл с N запросами, только он будет крутиться не в приложении на сервере, так? или я не правильно понял?

мне бы сократить количество запросов к таблице Events, лучше до 1
8 сен 11, 11:37    [11246049]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте как избавиться от запроса в цикле? :)  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31984
DASTAD
спасибо, не сталкивался раньше с cross aplly

но насколько я понял из его описания, это что то вызова процедуры для каждой строки таблицы...
то есть будет тот же цикл с N запросами, только он будет крутиться не в приложении на сервере, так? или я не правильно понял?

мне бы сократить количество запросов к таблице Events, лучше до 1
Нет, запрос тут вообще будет 1

Если бы там вместо подзапроса был действительно вызов процедуры, то тогда было бы по одному вызову на строку.
8 сен 11, 11:48    [11246144]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте как избавиться от запроса в цикле? :)  [new]
aleks2
Guest
DASTAD
первая: Parameters (PTime: datetime, Pvalue: float, ...) - в ней хранятся некие параметры объекта
вторая: Events (ETime: dateTime, Evalue: float, ...) - в ней хранятся описание событий

объект - печь
Pvalue - температура
Evalue - количество угля(тонны), загруженного в печь

where Etime>Pvalue(i) and Etime<=Pvalue(i+1))


Это просто восхищает. Только истинно российский программер могет совместить уголь и время...
8 сен 11, 14:19    [11247565]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте как избавиться от запроса в цикле? :)  [new]
aleks2
Guest
declare @Parameters table (PTime datetime, Pvalue float, id int identity, primary key clustered(PTime, id)) 
declare @Events table (ETime dateTime, Evalue float, id int identity, primary key clustered(ETime, id)) 
declare @T1 datetime, @T2 datetime

;with
PE as(
  select P.*, (select MAX(E.ETime) FROM  @Events E WHERE E.ETime<=P.PTime ) ETime FROM @Parameters P WHERE P.Ptime>@T1 and P.Ptime<=@T2
),
EE as (
  select E1.ETime, SUM(E2.Evalue) SUMEvalue FROM @Events E1 INNER JOIN @Events E2 on E2.ETime<=E1.ETime WHERE E1.ETime<=@T2 GROUP BY E1.ETime
)
select PE.PTime, PE.Pvalue, EE.SUMEvalue FROM  PE LEFT OUTER JOIN EE on PE.ETime=EE.ETime

8 сен 11, 14:37    [11247742]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте как избавиться от запроса в цикле? :)  [new]
Leran2002
Member

Откуда: Алматы, Казахстан
Сообщений: 53
Events (ETime: dateTime, Evalue: float, /* Огласите весь список, пожалуйста! */)

Интересная табличка! )
А время и уголь точно никаким полем нельзя выделить?
8 сен 11, 15:07    [11248122]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте как избавиться от запроса в цикле? :)  [new]
DASTAD
Member

Откуда:
Сообщений: 55
ё
так как-то
select ...
а вообще, странно что в Events не предусмотренна явная связь с Parmeters ...


Честь, хвала и благодарности - работает, да еще и быстро :)

а какая, на Ваш взгляд, могла бы быть связь?
11 сен 11, 19:03    [11260839]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить