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

MS Access SQL-捕获状态随时间的变化,sql,ms-access,ms-access-2007,jet-sql,Sql,Ms Access,Ms Access 2007,Jet Sql,我有一个Access 2007数据库,可以跟踪文档随时间的进展。进展如下: 创造 送审 回顾 送审 批准 我为文档状态的更改创建了一个历史记录表,其列如下: hist_id doc_id month step status datestamp 我创建了一个查询,返回月末的状态,如下所示: SELECT doc_id, month, step, status, datestamp FROM hist WHERE (((hist.datestamp) In (

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

  • 创造
  • 送审
  • 回顾
  • 送审
  • 批准
  • 我为文档状态的更改创建了一个历史记录表,其列如下:

    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
    的状态在
    19/02/2011
    上变成了
    revieved
    ,但这是它最后一次出现在上面的结果中。事实上,它应该在每个月之后以
    已审核
    的形式出现,直到后来成为
    发送审批

    所以我试图修改我的查询(或查询上面的查询)以提供如下结果

     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
    

    谢谢你的帮助。。。我真的不知道从哪里开始。

    这在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 
    

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

    多亏了Sparky回答中的一些线索,我才能够拼凑出适合我的东西

    台阶

  • 创建一个
    months
    表以包含月份列表,如
    2011-08
  • 创建
    month\u range
    查询,从实际文档中获取月份范围

    从月份中选择月份号,其中月份介于(历史记录的最小月份)和(历史记录的最大月份)之间


  • 使用
    month\u range
    hist
    表进行跨产品查询,其中
    hist.month\u no
    Wow,非常感谢!我还没有机会尝试,但我忘了在我的问题中提到,如果未获得批准,状态可以倒退,即
    发送以供批准
    返回到
    已审查
    。你知道你的解决方案是否能解决这个问题吗?i、 e.不查找一个月内的最高状态,而是查找该月内日期最高的状态。如果没有该月的记录,则应使用最新状态。如果没有,请告诉我,我将接受一个ppekIt,因为该查询似乎没有返回所需的输出。yy的1=1部件在MS Access中不工作。是否打算创建交叉联接?MS Access中的sytax是
    select*表1、表2
    ,因此我进行了更新以反映。它仍然不工作,我花了一些时间尝试调试。我想不出来,但从你的答案中得到一些线索(交叉连接,几个月的表格),我就能够自己从那里拼凑起来。谢谢你的帮助!
    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;