【问题标题】:SQL analogue of Pandas diff() function (1st discrete difference) [LAG function]Pandas diff() 函数的 SQL 类似物(第一个离散差分)[LAG 函数]
【发布时间】:2023-03-13 14:06:01
【问题描述】:

我正在寻找一种编写 SQL 查询的方法,该查询将对原始系列应用第一个离散差异。通过使用 Pandas 的 .diff() 方法,这在 Python 中非常简单:

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randint(0,100,size=(10, 2)), columns=list('AB'))

df["diff_A"]=df["A"].diff()
df["diff_B"]=df["B"].diff()

print(df)

我想要的输出显示在"diff_A""diff_B" 列中:

    A   B  diff_A  diff_B
0  36  14     NaN     NaN
1  32  13    -4.0    -1.0
2  31  87    -1.0    74.0
3  58  88    27.0     1.0
4  44  34   -14.0   -54.0
5   2  43   -42.0     9.0
6  15  94    13.0    51.0
7  46  74    31.0   -20.0
8  60   9    14.0   -65.0
9  43  57   -17.0    48.0

我使用 Oracle,但我绝对更喜欢干净的 ANSI 解决方案。

【问题讨论】:

    标签: python sql oracle pandas difference


    【解决方案1】:

    IIUC你可以使用解析LAG函数:

    with v as (
      select rowid as rn, a, b from tab
    )
    select
      a, b,
      a - lag(a, 1) over(order by rn) as diff_a,
      b - lag(b, 1) over(order by rn) as diff_b
    from v
    order by rn;
    

    PS 最好使用真实的列(如日期)进行排序,因为rowid can be changed

    例如:

    select
      a, b,
      a - lag(a, 1) over(order by inserted) as diff_a,
      b - lag(b, 1) over(order by inserted) as diff_b
    from tab;
    

    @MatBailie has posted a very good explanation:

    SQL 中的数据集是无序的。对于 LAG() 中的确定性结果 始终使用足够的 ORDER BY 子句。 (如果不存在这样的字段,则一个 应该在数据插入到 SQL 数据时/之前创建 放。 SQL 数据集的无序特性允许大量 可扩展性选项和优化选项可用。)

    SQL Fiddle test

    PSWindowing functions were added to the ANSI/ISO Standard SQL:2003 and then extended in ANSI/ISO Standard SQL:2008. Microsoft was late to this game. DB2, Oracle, Sybase, PostgreSQL and other products have had full implementations for years. SQL Server did not catch up until SQL 2012.

    【讨论】:

    • 并且按原始系列排序不是必需的操作(例如,它在测试示例中不会产生正确的结果)。例如,应该按日期订购,IIUC :)
    • @MarjanModerc,您的示例数据集中没有date 列;-)
    • 如果广告顺序是按时间顺序排列的,你不应该(order by rowid)
    • SQL 中的数据集是无序的。对于LAG() always 中的确定性结果,请使用足够的ORDER BY 子句。 (如果不存在这样的字段,则应在将数据插入 SQL 数据集时/之前创建一个。SQL 数据集的无序性质允许大量可伸缩性选项和优化选项可用.)
    • @Spade 我同意。我只是在试图与 OP 进行交流时进行如此冗长的评论,以至于他们 真的 应该在他们的 SQL 表中添加一个额外的列。 Pandas 使用隐式排序的数据集,可以更改位置,可以通过位置引用单个行等。SQL 采用更灵活的方法,允许使用多个不同的顺序来处理单个数据集,但是 OP 负责提供断言确定性顺序所需的字段。
    【解决方案2】:

    我发布此答案只是因为我能够在接受的答案中的 cmets 之后将结果复制到 SQLFiddle 中。除了rowid 事后改变之外,还有一个有效的论据为什么这个更简单的答案不起作用。

    select
      a, b,
      a - lag(a, 1) over(order by rowid) as diff_a,
      b - lag(b, 1) over(order by rowid) as diff_b
    from tab;
    

    【讨论】:

    • 我在测试时遇到了一个愚蠢的语法错误,我误解了 SQL Fiddle 的错误...它给了我ORA-04044: procedure, function, package, or type is not allowed here 而不是table or view does not exist:(
    猜你喜欢
    • 2021-10-11
    • 2016-04-24
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-03
    • 1970-01-01
    相关资源
    最近更新 更多