【问题标题】:MS Access SQL - Capture changes in status over timeMS Access SQL - 捕获状态随时间的变化
【发布时间】:2011-09-04 10:08:04
【问题描述】:

我有一个 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 的状态在19/02/2011 上变为reviewed,但这是它最后一次出现在上面的结果中。它实际上应该在之后的每个月中显示为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

感谢您的帮助...我真的不知道从哪里开始。

【问题讨论】:

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


    【解决方案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 
    

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

    【讨论】:

    • 哇,非常感谢!我没有机会尝试 ityet,但我忘了在我的问题中提到状态可以倒退,即如果没有得到批准,sent for approval 会返回到reviewed。你知道你的解决方案是否能适应这种情况吗?即不查找一个月中最高的状态,而是查找该月中日期最高的状态。
    • 应该,如果当月没有记录,则使用最近的状态。如果没有,请告诉我,我会参加 ppek
    • 查询似乎没有完全返回所需的输出。 yy 中的 1=1 部分在 MS Access 中不起作用。是否打算创建交叉连接? MS Access 中的语法是select * from table1, table 2,所以我已经更新以反映。它仍然无法正常工作,我花了一些时间尝试调试。我想不通,但是从你的回答中得到一些线索(交叉连接,几个月的表格),我能够从那里自己拼凑起来。感谢您的帮助!
    【解决方案2】:

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

    步骤

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

      SELECT month_no FROM months WHERE month BETWEEN(最小的历史月份)和(最大的历史月份)

    3. month_rangehist 表执行叉积查询,其中hist.month_no month_range.month

    4. 上述步骤留下了一个表格,其中每个文档每月有多个状态更改。只需在 month_nodoc_no 上进行 GROUP BY,在 SELECT 中使用 max(hist_id)

    5. 使用hist_id 将上面的结果与hist 表进行INNER JOIN 以访问状态

    我使用的确切最终查询如下所示......

    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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-19
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-05
      • 2020-06-01
      • 1970-01-01
      相关资源
      最近更新 更多