2

我有一个 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

但我真正需要的是我的查询,以便在几个月内返回状态没有改变的文档。例如, documenta的状态变为reviewedon 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

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

4

2 回答 2

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 

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

于 2011-09-04T13:51:13.203 回答
1

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

脚步

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

    SELECT month_no FROM months WHERE month BETWEEN(最小月份为 hist)和(最大月份为 hist)

  3. month_range使用和hist表进行交叉产品查询,其中hist.month_no<=month_range.month

  4. 上面的步骤留下了一个表格,每个文档每个月都有多个状态更改。只需 GROUP BY onmonth_nodoc_nowithmax(hist_id)在 SELECT

  5. INNER JOIN 将上面的结果与用于访问状态的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;
于 2011-09-06T07:38:51.773 回答