【问题标题】:Subtract two records of the same column in a table减去表中同一列的两条记录
【发布时间】:2012-06-22 09:54:39
【问题描述】:

我正在使用 PostgreSQL,我想减去同一张表的两条记录并在同一个查询中使用结果。

这是表格:

分数

6
8
9


结果

6
2
1

我想做什么:

Result = Score(i) - Score(i-1)

最后我想要这些结果的总和。在我的示例中,sum(result) 必须是 9。

【问题讨论】:

    标签: sql postgresql window-functions


    【解决方案1】:

    您需要一些方法来确定score 中的行顺序。关系数据库中的表中没有“自然顺序”。所以我假设你有一个id(或时间戳或其他东西)来订购你的记录。还是i 保证在每一行中都更大?然后你可以通过i订购。

    查询本身很简单——一旦你发现window functions

    SELECT i - lag(i, 1, 0) OVER (ORDER BY id) AS result
    FROM   score
    ORDER  BY id;
    

    包括@Clodoaldo 的改进(见评论)。

    lag(i, 1, 0) OVER (ORDER BY id)
    

    等价于,但比:

    COALESCE(lag(i) OVER (ORDER BY id), 0)
    

    目的是覆盖第一行没有前行的特殊情况。
    Demo on sqlfiddle.

    sum(result) 是微不足道的,因为根据您的描述,它必然等于最后一个 i

    SELECT i
    FROM   score
    ORDER  BY id DESC
    LIMIT  1;
    

    【讨论】:

    • +1 但是使用lag(i, 1, 0) 代替coalesce 不是更好吗?
    • @Clodoaldo:我同意,这更简单。用你的想法更新了答案。
    • @ErwinBrandstetter 非常感谢您的解释,但我的意思是总和是列结果的总和,所以这里是 6 + 2 + 1 给出 9 但巧合与上次相同分数的价值谢谢
    • @Lily:根据您的描述,这不是巧合而是逻辑结果。如果您有不同的结果,请提供另一个示例。
    【解决方案2】:

    类似

    SELECT SUM(COALESCE(rx.diff,rx.val))
      FROM
    (SELECT x.val,
            x.val - lag(x.val) over () as diff
      FROM (SELECT unnest(ARRAY[6,8,9]) as val) AS x) AS rx
    

    用你的表选择代替我的 unnest,它只是根据你的例子生成数据。

    【讨论】:

    • 感谢您的评论,但是如果我想要一个我不知道它是条目的表格或者它有无限条目,这意味着我不能将数组放在这种表格中,我该怎么办?还是不可能做到这一点?
    • @Lily:Gavin 示例中的数组显然只是为了提供示例值,而不是您的解决方案的一部分。但是,缺少的一件事是ORDER BY 子句。没有它,lag() 的结果是(特定于实现的)任意的。另外,COALESCE 放错地方了。
    猜你喜欢
    • 2018-05-21
    • 1970-01-01
    • 2016-09-20
    • 2021-12-03
    • 2019-11-09
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多