如何选择以前的行价?

时间:2009-07-01 07:07:44

标签: ms-access

如何从SELECT语句的上一结果行获取值

如果我们有一个名为cardevent的表并且有行[ID(int),Value(Money)]并且我们有一些行,例如

ID --Value

1------70 
1------90
2------100
2------150
2------300 
3------150 
3------200 
3-----250 
3-----280 

等......

如何制作一个查询,以获取每个行ID,值以及数据显示如下的上一行值

ID --- Value ---Prev_Value

1 ----- 70 ----------  0 
1 ----- 90 ---------- 70
2 ----- 100 --------  90 
2 ------150 -------- 100
2 ------300 -------- 150
3 ----- 150 -------- 300 
3 ----- 200 -------- 150 
3 ---- 250 -------- 200 
3 ---- 280 -------- 250 

等等。

我做了以下查询,但是在大量数据中表现如此糟糕

SELECT cardevent.ID, cardevent.Value, 
      (SELECT F1.Value
       FROM cardevent as F1 
       where F1.ID = (SELECT  Max(F2.ID)
                      FROM cardevent as F2 
                      WHERE F2.ID < cardevent.ID)
      ) AS Prev_Value
FROM cardevent

那么有人可以帮我找到解决这个问题的最佳方案吗?

4 个答案:

答案 0 :(得分:6)

这个应该适用于两个数据库:

SELECT cardevent.ID, cardevent.Value, 
  (SELECT TOP 1 F1.Value
   FROM cardevent as F1
   WHERE F1.ID < cardevent.ID
   ORDER BY F1.ID DESC
   ) AS Prev_Value
FROM cardevent

更新:假设ID不是唯一的,但ID和Value的组合是唯一的(您必须指定在表上强制订购的内容,因此您知道什么是前一行),您必须使用此查询:

select cardevent.ID, cardevent.Value, 
    (select TOP 1 F1.Value from cardevent as F1
     where (F1.ID < cardevent.ID) or (F1.ID = cardevent.ID and F1.Value < cardevent.Value)
     order by F1.ID DESC, F1.Value DESC
    ) AS Prev_Value
from cardevent 

答案 1 :(得分:3)

尝试这样的事情:

SELECT C.ID, C.Value, COALESCE(C1.Value, 0)
FROM cardevent C
    LEFT JOIN cardevent C1
    ON C1.Id = (SELECT MAX(id) FROM cardevent C2 where C2.Id < C.Id)

答案 2 :(得分:-1)

以下表现如何?

SELECT F1.ID, F1.Value, F3.Value
FROM cardevent F1
     INNER JOIN (
        SELECT F1.ID, mID = MAX(F2.ID)
        FROM cardevent F1
             INNER JOIN cardevent F2 ON F2.ID < F1.ID
        GROUP BY F1.ID
      ) F2 ON F2.id = F1.ID
     INNER JOIN cardevent F3 ON F3.ID = F2.mID
UNION ALL
SELECT F1.ID, F1.Value, 0
FROM cardevent F1
     INNER JOIN (
        SELECT ID = MIN(ID) 
        FROM cardevent
      ) F2 ON F2.ID = F1.ID
ORDER BY 1

答案 3 :(得分:-1)

我更喜欢TOP 1而不是MAX(...),恕我直言也应该更快:

SELECT      C.ID, C.Value, COALESCE(C1.Value, 0)
FROM        cardevent C
LEFT JOIN   cardevent C1
        ON  C1.ID = (SELECT TOP 1 C2.ID FROM cardevent C2 WHERE C2.ID < C.ID ORDER BY C2.ID)