MS Access SQL - 捕获状态随时间的变化

时间:2011-09-04 10:08:04

标签: sql ms-access ms-access-2007 jet-sql

我有一个Access 2007数据库,可以跟踪文档随时间的变化。进展如下:

  1. 创建
  2. 已发送以供审核
  3. 评价
  4. 已发送审批
  5. 已批准
  6. 我已经创建了一个历史记录表,用于更改文档状态,其中包含以下列:

    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 个答案:

答案 0 :(得分:1)

这适用于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 

我建议单独运行每个内部查询以帮助跟踪正在执行的操作...

答案 1 :(得分:1)

感谢Sparky回答的一些线索,我能够拼凑出对我有用的东西。

步骤

  1. 创建一个months表,其中包含2011-08
  2. 等月份列表
  3. 创建month_range查询以获取实际文档的月份范围

    SELECT month_no FROM months月份BETWEEN(hist的minium月份)AND(hist的最大月份)

  4. 使用month_rangehist表格进行跨产品查询,其中hist.month_no< = month_range.month

  5. 上面的步骤会使每个文档每月有多个状态更改。只需month_no上的GROUP BY和doc_no中的max(hist_id)

  6. INNER使用hist使用hist_id表格加入上面的结果以获取状态
  7. 我使用的确切最终查询看起来像这样......

    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;