MS Access SQL - захват изменений состояния с течением времени - PullRequest
2 голосов
/ 04 сентября 2011

У меня есть база данных Access 2007, которая отслеживает прогресс документа во времени. Прогрессия идет как:

  1. Создан
  2. Отправлено на проверку
  3. Отзыв
  4. Отправлено на утверждение
  5. Утверждена

Я создал таблицу истории изменений статуса документа с такими столбцами:

hist_id    doc_id    month   step    status  datestamp

Я создал запрос, который возвращает статусы на конец месяца, например:

SELECT doc_id, month, step, status, datestamp
FROM hist
WHERE (((hist.datestamp) In 
(
      Select Top 1 h.[datestamp]
      From hist as h
      Where h.[doc_id] = hist.[doc_id] and h.[month] = hist.[month]
      Order By h.[datestamp] DESC))
)
ORDER BY month, doc_id DESC;

чтобы получить ....

doc_id  month   step status             datestamp
a       2011-01 2    sent for review    18/01/2011
b       2011-02 1    created            01/02/2011
a       2011-02 3    reviewed           19/02/2011
c       2011-03 1    created            07/03/2011
d       2011-03 1    created            08/03/2011
e       2011-06 1    created            14/06/2011
f       2011-07 1    created            05/07/2011
g       2011-07 4    sent for approval  18/07/2011
h       2011-07 2    sent for review    14/07/2011
f       2011-08 3    reviewed           29/08/2011
g       2011-08 5    approved           17/08/2011
h       2011-08 1    created            10/08/2011
e       2011-09 3    reviewed           17/09/2011

Но что мне действительно нужно, так это мой запрос на возврат документов в месяцах, для которых статус не изменился. Например, статус документа a стал reviewed на 19/02/2011, но это последний раз, когда он появляется в результатах выше. Фактически он должен отображаться через каждый месяц как reviewed, пока не станет sent for approval.

Поэтому я пытаюсь изменить свой запрос (или запросить вышеупомянутый запрос), чтобы получить результаты, как показано ниже ...

 doc_id month   step    status          datestamp
a   2011-01 2   sent for review     18/01/2011
a   2011-02 3   reviewed        19/02/2011
b   2011-02 1   created         01/02/2011
a   2011-03 3   reviewed        19/02/2011
b   2011-03 1   created         01/02/2011
c   2011-03 1   created         07/03/2011
d   2011-03 1   created         08/03/2011
a   2011-04 3   reviewed        19/02/2011
b   2011-04 1   created         01/02/2011
c   2011-04 1   created         07/03/2011
d   2011-04 1   created         08/03/2011
a   2011-05 3   reviewed        19/02/2011
b   2011-05 1   created         01/02/2011
c   2011-05 1   created         07/03/2011
d   2011-05 1   created         08/03/2011
a   2011-06 3   reviewed        19/02/2011
b   2011-06 1   created         01/02/2011
c   2011-06 1   created         07/03/2011
d   2011-06 1   created         08/03/2011
e   2011-06 1   created         14/06/2011
a   2011-07 3   reviewed        19/02/2011
b   2011-07 1   created         01/02/2011
c   2011-07 1   created         07/03/2011
d   2011-07 1   created         08/03/2011
e   2011-07 1   created         14/06/2011
f   2011-07 1   created         05/07/2011
g   2011-07 4   sent for appr   18/07/2011
h   2011-07 2   sent for rev    14/07/2011
a   2011-08 3   reviewed        19/02/2011
b   2011-08 1   created         01/02/2011
c   2011-08 1   created         07/03/2011
d   2011-08 1   created         08/03/2011
e   2011-08 1   created         14/06/2011
f   2011-08 3   reviewed        29/08/2011
g   2011-08 5   approved        17/08/2011
h   2011-08 1   created         10/08/2011
a   2011-09 3   reviewed        19/02/2011
b   2011-09 1   created         01/02/2011
c   2011-09 1   created         07/03/2011
d   2011-09 1   created         08/03/2011
e   2011-09 1   reviewed        17/09/2011
f   2011-09 3   reviewed        29/08/2011
g   2011-09 5   approved        17/08/2011
h   2011-09 1   created         10/08/2011

Спасибо за вашу помощь ... Я действительно даже не знаю, с чего начать.

Ответы [ 2 ]

1 голос
/ 06 сентября 2011

Благодаря некоторым подсказкам из ответа Спарки, я смог собрать воедино то, что мне подходит.

Steps

  1. Создайте таблицу months, которая будет содержать список месяцев, например 2011-08
  2. Создание запроса month_range для получения диапазона месяцев из фактических документов

    ВЫБРАТЬ month_no ИЗ месяцев, ГДЕ месяц между (минимальный месяц для истории) И (максимальный месяц для истории)

  3. Выполните перекрестный запрос продукта с таблицами month_range и hist, где hist.month_no <= <code>month_range.month

  4. Приведенный выше шаг оставляет таблицу с несколькими изменениями статуса в месяц для каждого документа. Просто GROUP BY на month_no и doc_no с max(hist_id) в SELECT

  5. INNER СОЕДИНИТЕ результат сверху с таблицей hist, используя hist_id, чтобы получить доступ к статусу

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

SELECT xx.month_no, xx.swp, xx.hist_id, h.status

FROM 
(
     SELECT zz.month_no, zz.swp, Max(zz.hist_id) AS hist_id
     FROM 
     (
          SELECT * FROM month_range AS mr, hist AS h 
          WHERE h.[first_of_month] <= mr.[first_of_month]
     ) zz
     GROUP BY zz.month_no, zz.swp

)  xx 

INNER JOIN hist as h ON xx.hist_id = h.hist_id;
1 голос
/ 04 сентября 2011

Это работает в SQL и не использует никаких специальных функций, поэтому должно работать и в MS-ACCESS SQL.

Во-первых, вам нужно будет создать таблицу по месяцам.

create table monthly (monthN char(7))

insert into monthly values('2011-01')
insert into monthly values('2011-02')
...

и заполните его всеми нужными месяцами.

После создания этой таблицы следующий запрос должен вернуть то, что вы ищете:

select d1.doc_id,d1.monthN,d1.step,d1.status,d1.dateStamp
from monthly m1
join docs d1 on d1.monthN=m1.monthN
union
select d2.doc_id,zz.monthN,d2.step,d2.status,d2.dateStamp
from docs d2
join
(
    select aa.doc_id,aa.monthN,bb.EndM from
    (
    select yy.doc_id,yy.monthN from
    (   
        select d3.doc_id,m2.monthN
        from monthly m2
        join (select distinct doc_id from docs) d3 on 1=1
        ) yy
    left join docs xx on xx.doc_id=yy.doc_id and xx.monthN=yy.MonthN
    where xx.hist_id is null
    ) aa
    join (select doc_id,MIN(monthN) as startM,MAX(monthN) as EndM 
          from docs group by doc_id) 
          bb on bb.doc_id=aa.doc_id and aa.monthN>=bb.StartM
) zz
on zz.doc_id=d2.doc_id and zz.EndM=d2.monthN
order by d1.monthN,d1.doc_id 

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

...