比较每个合同的最后一个记录到最后一个记录

时间:2011-02-18 11:38:19

标签: sql ms-access

为了简单起见,我的问题类似于THIS QUESTION, PART 2,唯一的问题是,我没有运行Oracle,因此无法使用rownumbers。

对于那些需要更多信息和示例的人:

我有一张桌子

  contractId date          value    
  1          09/02/2011     A         
  1          13/02/2011     C          
  2          02/02/2011     D   
  2          08/02/2011     A  
  2          12/02/2011     C  
  3          22/01/2011     C  
  3          30/01/2011     B  
  3          12/02/2011     D    
  3          21/01/2011     A

编辑:为ContractID添加了另一行。由于我自己有一些代码,但会显示以下内容:

  contractId date          value    value_old
  1          09/02/2011     A                  
  2          08/02/2011     A         D
  3          30/01/2011     B         C    
  3          30/01/2011     B         A 

但那是我想要的!结果应该仍然如下!

现在我想在给定日期之前选择最后一条记录,并将其与之前的值进行比较。 假设“给定日期”在本例中为11/02/2011 ,输出应如下所示:

  contractId date          value    value_old
  1          09/02/2011     A                  
  2          08/02/2011     A         D
  3          30/01/2011     B         C    

我确实有查询选择给定日期之前的最后一条记录。这是容易的部分。但要选择之前之前的最后一条记录,我就迷失了......

我真的希望我能在这里得到一些帮助,这几天一直在打破这个问题并在网上和堆栈溢出中寻找答案。

2 个答案:

答案 0 :(得分:3)

一种可能性:

SELECT a.contractId, a.Date, a.Value, (SELECT Top 1 b.[Value] 
        FROM tbl b 
        WHERE b.[Date] < a.[Date] And b.ContractID=a.ContractID
        ORDER BY b.[Date] Desc) AS Old_Value
FROM tbl AS a
WHERE a.Date IN 
       (SELECT TOP 1 b.Date 
        FROM tbl b 
        WHERE b.ContractID=a.ContractID
        AND b.Date < #2011/02/11#
        ORDER BY b.date DESC)

答案 1 :(得分:0)

按照承诺,我也会发布我的回答。虽然在这一点上,我仍然认为Remou的答案更好,因为代码更短,看起来效率更高(调用同一个表的次数更少)。但是这里有:

查询1:

SELECT c.contractID, c.firstofdates, a.value, d.value, d.date
FROM (table1 AS A RIGHT JOIN (SELECT b.cid,max(b.date) AS FirstOfdates
FROM table1 as B
where b.date < #02/11/2011#
GROUP BY b.contractID    )  AS c ON (a.date = c.firstofdates) AND (a.contractID =   c.contractID)) 
LEFT JOIN (select e.contractID, e.date, e.value
from table1 as e
)  AS d ON (d.date < c.firstofdates) AND (d.contractID = c.contractID);

此查询实际上为第三个contractID的额外行提供了结果。

QUERY2:

SELECT b.contractID, max(a.date) AS olddate
FROM table1 AS a RIGHT JOIN (select contractID, firstofdates 
from Query1)  AS b ON (a.contractID= b.contractID) AND (a.date < b.firstofdates)
GROUP BY b.contractID;

然后结合两者:

QUERY3:

SELECT Query1.contractID, Query1.firstofdates AS [date], Query1.A.value AS [value], Query1.d.value  AS [old value]
FROM Query1 RIGHT JOIN Query2 
ON (Query1.date=Query2.olddate or Query2.olddate is null) AND   (Query1.cid = Query2.cid);