【问题标题】:How to get a value from previous result row of a SELECT statement?如何从 SELECT 语句的前一个结果行中获取值?
【发布时间】:2009-04-12 19:02:13
【问题描述】:

如果我们有一个名为 FollowUp 的表并且有行 [ ID(int) , Value(Money) ] 我们有一些行,例如
ID --值
1--------70
2--------100
3--------150
8-----200
20-----250
45-----280
我们要创建一个 SQL 查询,获取每个行 ID、值和数据显示如下的前一个行值
ID --- 值 --- Prev_Value
1 ----- 70 ---------- 0
2 ----- 100 -------- 70
3 ----- 150 -------- 100
8 ----- 200 ----- 150
20 ---- 250 -------- 200
45 ---- 280 -------- 250

我进行了以下查询,但我认为它在大量数据中的性能非常糟糕

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

那么任何人都可以帮助我为此类问题找到最佳解决方案吗?

【问题讨论】:

标签: sql ms-access


【解决方案1】:

这个 sql 的性能应该比你上面的那个更好,尽管这些类型的查询往往会有点性能密集型......所以你可以放入其中以限制你正在查看的数据集大小的任何东西都会有所帮助极大地。例如,如果您正在查看特定日期范围,请将其放入。

SELECT followup.value, 
    ( SELECT TOP 1 f1.VALUE 
      FROM followup as f1 
      WHERE f1.id<followup.id 
      ORDER BY f1.id DESC
    ) AS Prev_Value
FROM followup

HTH

【讨论】:

    【解决方案2】:

    您可以使用 OVER 语句生成递增的行号。

    select
        rownr = row_number() over (order by id)
    ,   value
    from your_table
    

    使用数字,您可以轻松查找上一行:

    with numbered_rows
    as (
        select
            rownr = row_number() over (order by id)
        ,   value
        from your_table
    )
    select
        cur.value
    ,   IsNull(prev.value,0)
    from numbered_rows cur
    left join numbered_rows prev on cur.rownr = prev.rownr + 1
    

    希望这是有用的。

    【讨论】:

    • 那是什么 SQL 方言?这肯定不是 Jet SQL。
    • SQL Server 2005(我假设它是 Access 背后的后端)
    【解决方案3】:

    这不是您实际问题的答案。

    相反,我觉得您从错误的方向解决问题: 在正确规范化的关系数据库中,每个表的元组(“行”)应该包含对其他数据库项的引用,而不是实际值。维护元组之间的这些关系属于代码库的数据插入部分。 也就是说,如果包含具有最接近、更小的 id 编号的元组的值,则确实属于您的数据模型。

    如果了解先前值的要求来自应用程序的视图部分 - 即需要以某种方式格式化数据的单个视图 - 您应该将内容拉出,按 id 排序,然后在查看特定代码中处理需求。

    在您的情况下,我假设知道先前元组的值确实属于视图代码而不是数据库。

    编辑:您确实提到您将它们分开存储并且只想对其进行查询。尽管如此,应用程序代码可能是进行这种组合的更合乎逻辑的地方。

    【讨论】:

      【解决方案4】:

      将这些线拉入您的应用程序并在那里计算先前的值怎么样?

      【讨论】:

        【解决方案5】:

        创建一个存储过程并使用游标来迭代和生成行。

        【讨论】:

        • Access 2007 中的存储过程?
        【解决方案6】:

        你可以使用'LAG'函数。

             SELECT ID,
                    Value,
                    LAG(value) OVER(ORDER BY ID) AS Prev_Value
             FROM FOLLOWUP;
        

        【讨论】:

        • Access SQL 不支持LAGOVER
        猜你喜欢
        • 2011-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-11
        • 1970-01-01
        • 2017-03-26
        • 2022-11-17
        • 1970-01-01
        相关资源
        最近更新 更多