Как узнать состояние на момент времени

Модераторы: kdv, CyberMax

Ответить
SAV
Сообщения: 54
Зарегистрирован: 19 авг 2006, 17:59

Как узнать состояние на момент времени

Сообщение SAV » 02 май 2007, 13:50

Нужна помощь с запросом есть таблица(журнал) выполненых действий над некими объектами:
CREATE TABLE G_HIST_1 (
ID_ACT D_INT,
ID_OBJ D_STRING,
OBJ_VERS D_INT NOT NULL PRIMARY KEY
P_PERFORMER D_SHORTSTRING,
P_DATE D_DATETIME,
P_DESC D_BLOBSTRING ,

P_1 D_INT ,
P_2 D_DOUBLE ,
....
P_5 D_BLOBSTRING,
...
);
В зависимости от ID_ACT заполняются поля P_1 - P_n,то есть если
ID_ACT=1 то P_1=4,если ID_ACT=2 - то P_1=5 и P_2=5.5,если ID_ACT=2 то P_5='qwerty'.Вопрос такой как выбрать все P_xx,на заданные момент времени и какие действия (ID_ACT,P_PERFORMER...)были выполнены до выбранного момена времени?

mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

Сообщение mdfv » 02 май 2007, 14:55

Аж интересно стало, что вы хотите...
Нельзя ли поподробнее и пример того что должно получиться?

SAV
Сообщения: 54
Зарегистрирован: 19 авг 2006, 17:59

Сообщение SAV » 02 май 2007, 15:59

Таблица данных
ID_ACT ID_OBJ OBJ_VERS P_PERFORMER P_DATE P_DESC P_1 P_2 P_5
1| 1| 7| SYSDBA| 2007.01.07| 4|null|null
1| 2| 8| SYSDBA| 2007.01.06| 5| null| null
2| 1| 5| SYSDBA| 2007.01.05| 5|5.5| null
1| 7| 14| SYSDBA| 2007.01.04| 6| null| null
3| 1| 3| SYSDBA| 2007.01.03| null|null|'Q1'
1| 4| 2| SYSDBA| 2007.01.02| 7|null|null
3| 1| 1| SYSDBA| 2007.01.01| null| null|'Q2'
Так вот нужно выбрать значения для ID_OBJ==1 P_1,P_2,P_5 на любое число(например на 2007.01.04 P_1=6,P_2=null,P_5=Q1 ,а на 2007.01.05 P_1=5,P_2=5.5,P_5=Q1). И второе выбрать данные по последним выполненным действиям (например для даты 2007.01.07 последние выполненые операции ID_ACT=1-2007.01.07,ID_ACT=2-2007.01.05,ID_ACT=3-2007.01.03 )

mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

Сообщение mdfv » 02 май 2007, 17:24

И второе выбрать данные по последним выполненным действиям (например для даты 2007.01.07 последние выполненые операции ID_ACT=1-2007.01.07,ID_ACT=2-2007.01.05,ID_ACT=3-2007.01.03 )
Если я правильно понял суть, то примерно так(FB2):

Код: Выделить всё

select GH1.ID_ACT , max(GH2. P_DATE)
from
(select distinct ID_ACT from G_HIST_1 where P_DATE<= :P_DATE
) GH1
join G_HIST_1 GH2
on (GH1.ID_ACT=GH2.ID_ACT and P_DATE<= :P_DATE)
group by 1
rows 3
или так чуть быстрее

Код: Выделить всё

select GH1.ID_ACT , (select max(GH2. P_DATE)  from G_HIST_1 GH2 where P_DATE<= :P_DATE and GH1.ID_ACT=GH2.ID_ACT )
from
(select distinct ID_ACT from G_HIST_1 where P_DATE<= :P_DATE
) GH1
rows 3
хотя это и неэффективно получится(distinct), зато универсально, можно при желании оптимизировать с учетом реальных данных.
и (или) на процедуре сделать.

mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

Сообщение mdfv » 02 май 2007, 17:42

Так вот нужно выбрать значения для ID_OBJ==1 P_1,P_2,P_5 на любое число(например на 2007.01.04 P_1=6,P_2=null,P_5=Q1 ,а на 2007.01.05 P_1=5,P_2=5.5,P_5=Q1).
Если я правильно понял то здесь надо до первого не null в P_1 и P_5 вниз по дате спускаться для данного ID_OBJ ? Тогда возможно быстрее в процедуре .

SAV
Сообщения: 54
Зарегистрирован: 19 авг 2006, 17:59

Сообщение SAV » 02 май 2007, 21:00

mdfv писал(а):Если я правильно понял то здесь надо до первого не null в P_1 и P_5 вниз по дате спускаться для данного ID_OBJ ? Тогда возможно быстрее в процедуре .
Ага именно так,до первого не null,я тоже хотел поцедуру замутить,но таких таблиц несколько они однообразны но P_xx у них разные,я для каждой из них делать процедуры слишком накладно. Собственно это журнал выполненных действий с результатами выполнения и мне иногда надо узнавать состояние объекта на N-ый момент времени.

mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

Сообщение mdfv » 02 май 2007, 21:41

Ну если на несколько таблиц, то можно, хоть тут и не советуют,
сделать в одной процедуре execute statement и подставлять туда нужные имена таблиц параметром и имена различающихся полей.
А если и процедуры не хочется, то можно совсем извратиться и запихать в execute block.
Я на execute block-ах отчеты делаю, процедуры плодить не надо на каждую ерунду. Правда и здесь нужна осторожность.

SAV
Сообщения: 54
Зарегистрирован: 19 авг 2006, 17:59

Сообщение SAV » 02 май 2007, 21:58

mdfv писал(а):Ну если на несколько таблиц, то можно, хоть тут и не советуют,
сделать в одной процедуре execute statement и подставлять туда нужные имена таблиц параметром и имена различающихся полей.
А если и процедуры не хочется, то можно совсем извратиться и запихать в execute block.
Я на execute block-ах отчеты делаю, процедуры плодить не надо на каждую ерунду. Правда и здесь нужна осторожность.
Идею понял,вся разница втом что всю таблицу тащить на клиента не придётся,а перебрать её на серваке. Я вот уже целый день между делом думаю как бы так поэффективнее сделать.

Ответить