Sql 如何选择上一行值?
如何从SELECT语句的上一个结果行中获取值 例如,如果我们有一个名为cardevent的表,其中有行[IDIT,ValueMoney],其中有一些行Sql 如何选择上一行值?,sql,ms-access,Sql,Ms Access,如何从SELECT语句的上一个结果行中获取值 例如,如果我们有一个名为cardevent的表,其中有行[IDIT,ValueMoney],其中有一些行 ID --Value 1------70 1------90 2------100 2------150 2------300 3------150 3------200 3-----250 3-----280 等等 如何进行一次查询,以获取数据显示在其中的每一行ID、值和上一行值,如下所示 ID --- Value ---Pre
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
有人能帮我找到解决这个问题的最佳方案吗?试试这样的方法:
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)
对于这两个数据库,这一个应该都可以正常工作:
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和值的组合是唯一的,则必须指定对表施加排序的内容,以便知道前一行是什么,必须使用此查询:
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
以下内容如何执行
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
我更喜欢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)
为什么用2个不同的RDBMS标记?复制到另一个用户,另一个表名:必须是一个家庭作业问题…和:+1。这似乎是所有给定解决方案的最快速度。它似乎编译成与MicSim的解决方案相同的执行计划-如果仔细观察,它是有意义的。我认为两者都可以。我没有仔细查看实际的执行计划,只是查看了SQLServer给出的百分比。所有的解决方案都工作正常,主要区别在于执行时间和可读性。您的解决方案速度最快或与MicSim的解决方案一样快,且可读性最强。我的是。。。嗯,对于COALESCE的使用来说,不太好+1。虽然COALESCE在MS Access中不起作用,但它在SQL中是一个非常有用的命令,只有SQL Server。@MicSim-我使用了您的查询,但它显示错误子查询最多可以返回一条记录prev_value fieldOutput中没有显示任何内容,显示如下。。。。PERSONID CARDEVENTDATE Expr1002上一个值名称?名称?名称?名称?名字?名字?名字?名字?名字?名字?名字?名字?名字?名字?Name?Name?Name?Name?Name?刚才用Access 2000测试了上面的查询,这里没有2003,它正在工作。也许您已经扩展/修改了查询?您的查询工作正常,但Id对于值来说一直都是一样的。实例id,值-1100、2200、2400、2500、31003200以此类推。。所以结果是。。1 100 0、2 200 100、2 400 200、2 500 400、3 100 500、3 200 100等等。@MicSim-我使用了您更新的查询,但它显示错误,子查询使用access 2003数据库最多只能返回一条记录,不接受合并function@Gopal:我不关心MSAccess中代码的效率,但是IIF和ISNULL应该有帮助:IIFISNULLC1.Value,0,C1.Value