Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Здравствуйте, уважаемые участники форума!
Прошу помощи в составлении запроса...
Есть следующая задача:
При помощи вызова процедуры Call getObjectsByModelAndClass('CNC','USR'); в таблицу ObjectsOfModelAndClass заносятся записи следующего вида:
ModelCode DataSetNum Num ClassCode Name BeginInterval EndInterval
CNC -1 14187 USR Azat 2019-01-07 15:15:00.0 2019-01-07 16:15:00.0
CNC -1 14167 USR BAA 2018-01-10 17:05:00.0 2018-01-10 18:53:00.0
CNC -1 11319 USR BUI 2019-12-07 15:14:00.0 2019-12-07 15:26:00.0
CNC -1 24457 USR EOV 2027-08-09 09:27:00.0 2028-08-09 08:42:00.0
* * * * * * * * * * * * * * *
Затем засчет вызова процедуры Call getElementaryPeriods('2008-08-02 00:27:46', '2008-12-10 17:43:28', 10); создается таблица ElementaryPeriods, которая содержит элементарные периоды заданного размера (в минутах):
BeginElementaryInterval EndElementaryInterval
2008-08-02 00:27:46.0 2008-08-02 00:30:00.0
2008-08-02 00:30:00.0 2008-08-02 00:40:00.0
2008-08-02 00:40:00.0 2008-08-02 00:50:00.0
2008-08-02 00:50:00.0 2008-08-02 01:00:00.0
* * * * * * * * * * *
Необходимо создать хранимую процедуру Call getObjectsByPeriods('2008-08-02 00:27:46', '2008-12-12 17:43:28');, которая будет обходить ElementaryPeriods и из ObjectsOfModelAndClass заносить в таблицу ObjectsOfPeriods объекты, которые попадают в каждый из заданных элементарных периодов.
Собственно, данную хранимку я написал:
Неактивен
Внутри курсора открывать ещё один курсор не нужно. Используете две переменных, одна счетчик, вторая предыдущее значение периода.
Если предыдущее значение периода совпадает с текущим, то счетчик не меняется, если нет, то счечик увеличивается на 1 и предыдущее значение периода обновляется на текущее.
Неактивен
Уважаемый, vasya!
Я так понимаю, нужно добавить что-то вроде этого:
Отредактированно NDS (18.04.2010 21:04:19)
Неактивен
Declare countNumOfPeriod integer default 0;
DECLARE previousBeginElemPeriod DATETIME DEFAULT '0000-00-00 00:00:00';
. . .
WHILE done = 0 DO
FETCH ElementaryPeriodsCursor INTO beginElemPeriod, endElemPeriod;
INSERT INTO ObjectsOfPeriods(NumOfPeriod,
....
select countNumOfPeriod,
....
where BeginInterval >= beginElemPeriod
and
EndInterval <= endElemPeriod
and
if (previousBeginElemPeriod=beginElemPeriod,1,countNumOfPeriod:=countNumOfPeriod+1);
Конструкция IF .. END IF; в начале курсора не нужна. Эта проверка проводится в части where самого запроса.
UPD: Первоначально неправильно написал условие, см исправленный вариант.
Неактивен
Что-то я не совсем не то сначала написал. См исправленный вариант в прошлом посте.
Неактивен
Что-то совсем клиника наступила. Такой вариант вроде похож на правду.
Declare countNumOfPeriod integer default 0;
DECLARE previousBeginElemPeriod DATETIME DEFAULT '0000-00-00 00:00:00';
. . .
WHILE done = 0 DO
FETCH ElementaryPeriodsCursor INTO beginElemPeriod, endElemPeriod;
INSERT INTO ObjectsOfPeriods(NumOfPeriod,
....
select countNumOfPeriod,
....
where BeginInterval >= beginElemPeriod
and
EndInterval <= endElemPeriod
and
if (previousBeginElemPeriod=beginElemPeriod,1,(countNumOfPeriod:=countNumOfPeriod+1) and (previousBeginElemPeriod:=beginElemPeriod));
Неактивен
Я извиняюсь))
опишите, пожалуйста, более подробно данные строки:
Отредактированно NDS (18.04.2010 21:29:11)
Неактивен
Понял. Таким образом можно проводить присвоение только пользовательских переменных.
Так будет работать:
set @countNumOfPeriod = 0;
set @previousBeginElemPeriod = '0000-00-00 00:00:00';
. . .
WHILE done = 0 DO
FETCH ElementaryPeriodsCursor INTO beginElemPeriod, endElemPeriod;
INSERT INTO ObjectsOfPeriods(NumOfPeriod,
....
select countNumOfPeriod,
....
where BeginInterval >= beginElemPeriod
and
EndInterval <= endElemPeriod
and
if (@previousBeginElemPeriod=beginElemPeriod,1,(@countNumOfPeriod:=@countNumOfPeriod+1) and (@previousBeginElemPeriod:=beginElemPeriod));
Неактивен
if (@previousBeginElemPeriod=beginElemPeriod,1,(@countNumOfPeriod:=@countNumOfPeriod+1) and (@previousBeginElemPeriod:=beginElemPeriod));
Если предыдущее значение периода совпадает с текущим (условие @previousBeginElemPeriod=beginElemPeriod), то будет возвращена 1.
Если же нет, то выполняется увеличение счетчика (@countNumOfPeriod:=@countNumOfPeriod+1) и переопределение предыдущего значения периода (@previousBeginElemPeriod:=beginElemPeriod). Каждая из этих операций возвращает true. true and true будет тоже true.
Таким образом наше условие if() в фильтре не забракует никаких строк (так как всегда возвращает true), а предназначено только для увеличения счетчика.
Неактивен
Уважаемый, vasya!
Благодарю за помощь и подробное объяснение!!! - с учетом последних исправлений все заработало...
Неактивен
Страниц: 1