选择值更改的行

时间:2010-12-20 07:00:13

标签: sql ms-access vba

我在访问数据库中有一个表,其中包含作业描述,项目,日期和所需金额的列。对于每个描述,我想为每个作业/项目组合选择第一个日期条目,以及金额更改的行。

所以,如果我有

Job        proj date     amt
Programmer 105  01-01-11 3
Programmer 105  01-02-11 3
Programmer 105  01-03-11 2
Programmer 105  01-04-11 2
Programmer 105  01-05-11 3
Programmer 110  01-03-11 1
Programmer 110  01-04-11 2
Programmer 110  01-05-11 3
Manager    105  01-01-11 1
Manager    105  01-02-11 2
Manager    105  01-03-11 2
Manager    105  01-04-11 2
Manager    105  01-05-11 2

我想选择

Programmer 105  01-01-11 3
Programmer 105  01-03-11 2
Programmer 105  01-05-11 3
Programmer 110  01-03-11 1
Programmer 110  01-04-11 2
Programmer 110  01-05-11 3
Manager    105  01-01-11 1
Manager    105  01-02-11 2

我有一张表格,其中包含可以使用的独特职位描述。

2 个答案:

答案 0 :(得分:2)

这可以通过分析(窗口)函数轻松完成,可以在Oracle / SQL-Server / etc中找到(Google用于lag,lead,first_value,last_value等),但是Access不支持它们,所以你必须自己加入这样的东西:

SELECT 
    rows.Job, rows.proj, rows.dte, curr.amt 
FROM
    ((SELECT Data.Job, Data.proj, Data.dte, 
        (SELECT max(dte) 
         FROM data as prev 
         WHERE prev.job = data.job and 
               prev.proj = data.proj and 
               prev.dte < data.dte) AS prev_dte 
     FROM Data) as [rows] 
     INNER JOIN Data AS curr 
               ON (rows.dte = curr.dte) AND 
                  (rows.proj = curr.proj) AND 
                  (rows.Job = curr.Job)
)
    LEFT JOIN Data AS prev 
         ON (rows.prev_dte = prev.dte) AND 
            (rows.proj = prev.proj) AND 
            (rows.Job = prev.Job) 
WHERE 
    prev.amt<>[curr].[amt] OR 
    prev.Job Is Null;

因此,名为[rows]的内联视图查找的最大日期小于表中的每个日期,然后返回内部联接以获取prev行的当前行和外部联接,以便您将获取第一行。

(代码格式有问题 - 抱歉。)

编辑:这是输出,我认为是你需要的。

Job         proj    dte             amt
Programmer  105     01/01/2011  3 
Programmer  105     03/01/2011  2 
Programmer  105     05/01/2011  3 
Programmer  110     03/01/2011  1 
Programmer  110     04/01/2011  2 
Programmer  110     05/01/2011  3 
Manager     105     01/01/2011  1 
Manager     105     02/01/2011  2 

答案 1 :(得分:2)

第一个条目将始终为nextamt:

SELECT j.Job,
    j.proj,
    j.Date,
    j.amt,
    (SELECT TOP 1 amt 
     FROM jobs q 
     WHERE q.job=j.job AND q.proj=j.proj AND q.date<j.date 
     ORDER BY [date] DESC) AS nextamt 
FROM jobs AS j 
WHERE ((SELECT TOP 1 amt 
        FROM jobs q 
        WHERE q.job=j.job AND q.proj=j.proj AND q.date<j.date 
        ORDER BY [date] DESC)) <>[amt] 
Or ((SELECT TOP 1 amt 
     FROM jobs q 
     WHERE q.job=j.job AND q.proj=j.proj AND q.date<j.date 
     ORDER BY [date] DESC)) Is Null