SQL查找前一行和当前行之间的差异

24

我正在尝试找到当前行和上一行之间的差异。但是,我却收到以下错误信息:

多部分标识符"tableName"无法绑定。

不确定如何解决这个错误。

谢谢!

输出应该如下所示:

columnOfNumbers     Difference
      1               NULL
      2               1
      3               1
      10              7
      12              2
      ....            ....

代码:

USE DATABASE;

WITH CTE AS 
(SELECT 
    ROW_NUMBER() OVER (PARTITION BY tableName ORDER BY columnOfNumbers) ROW,
    columnOfNumbers
    FROM tableName)
SELECT
    a.columnOfNumbers
FROM
    CTE a
    LEFT JOIN CTE b
    ON a.columnOfNumbers = b.columnOfNumbers AND a.ROW = b.ROW + 1

你使用哪个数据库? - Joseph B
1
你必须按列名进行分区。 - Dan Bracuk
1
可以省略 'partition by' 子句。 - Karl Kieninger
3个回答

47

如果您使用的是 SQL Server 2012 或更高版本,您可以使用 LAG 函数。

 SELECT columnOfNumbers
       ,columnOfNumbers - LAG(columnOfNumbers, 1) OVER (ORDER BY columnOfNumbers)
   FROM tableName
注意:LAG的可选第三个参数是:
默认值
当偏移处的scalar_expression为NULL时返回的值。 如果未指定默认值,则返回NULL。默认值可以是列、子查询或其他表达式,但不能是分析函数。默认值必须与scalar_expression类型兼容。

好的解决方案,但是对于第一行给出了错误结果:1而不是null。 - wvdz
5
啊,对了,我没有仔细阅读所需的样本输出。如果我们在LAG中省略第三个参数,默认为0,则会在第一行中给出一个空值。 - Karl Kieninger
1
我将其与使用ROW_NUMBER的其他发布解决方案进行了比较,但为了获得相同的可用数据,我添加了另一个LAG以获取上一条记录的主键,然后进行连接。与使用ROW_NUMBER连接相比,这种方法所需的时间少了一半以上。 - Inrego

30

请参考sqlFiddle

;WITH tblDifference AS
(
    SELECT ROW_NUMBER() OVER(ORDER BY id) AS RowNumber, columnOfNumbers 
    FROM tableName
)

SELECT cur.columnOfNumbers, cur.columnOfNumbers - previous.columnOfNumbers
FROM tblDifference cur
LEFT OUTER JOIN tblDifference previous
ON cur.RowNumber = previous.RowNumber + 1

2

我认为您不需要使用partition by语句:

WITH CTE AS (
      SELECT ROW_NUMBER() OVER (ORDER BY columnOfNumbers) as ROW,
             columnOfNumbers
      FROM tableName
     )
SELECT a.columnOfNumbers, a.columnOfNumbers - b.columnOfNumbers
FROM CTE a LEFT JOIN
     CTE b
     ON a.ROW = b.ROW + 1;

如果您需要它,应该输入列名而不是表名。

我尝试了这个查询,但第二列返回了NULLS。有什么建议吗? - ChaseHardin
@user3356901……它返回了“NULL”,因为我在您的条件中留下了“a.columnOfNumbers = b.columnOfNumbers”。 - Gordon Linoff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接