我需要计算表的两行之间的列差。有什么办法可以直接在SQL中执行此操作?我正在使用Microsoft SQL Server 2008。
我正在寻找这样的东西:
SELECT value - (previous.value) FROM table
假设“上一个”变量引用了最近选择的行。当然,通过这样的选择,我最终将在具有n行的表中选择n-1行,这可能不是,实际上正是我所需要的。
有可能吗?
我需要计算表的两行之间的列差。有什么办法可以直接在SQL中执行此操作?我正在使用Microsoft SQL Server 2008。
我正在寻找这样的东西:
SELECT value - (previous.value) FROM table
假设“上一个”变量引用了最近选择的行。当然,通过这样的选择,我最终将在具有n行的表中选择n-1行,这可能不是,实际上正是我所需要的。
有可能吗?
Answers:
SQL没有内置的顺序概念,因此您需要按某一列进行顺序才能使此顺序有意义。像这样:
select t1.value - t2.value from table t1, table t2
where t1.primaryKey = t2.primaryKey - 1
如果您知道如何对事物进行排序,但不知道如何在给定当前值的情况下获得先前的值(例如,您要按字母顺序进行排序),那么我不知道在标准SQL中执行此操作的方法,但是大多数SQL实现将具有扩展做到这一点。
如果可以对行进行排序以使每个行都不同,则这是一种适用于SQL Server的方法:
select rank() OVER (ORDER BY id) as 'Rank', value into temp1 from t
select t1.value - t2.value from temp1 t1, temp1 t2
where t1.Rank = t2.Rank - 1
drop table temp1
如果需要打破平局,可以向ORDER BY添加尽可能多的列。
LAG(ExpressionToSelect, NumberOfRowsToLag, DefaultValue)
。滞后的默认行数是1,但是您可以指定该行,并且在无法滞后时选择默认值,因为您位于集合的开始。
Oracle,PostgreSQL,SQL Server和许多其他RDBMS引擎具有称为的分析功能,LAG
并且LEAD
可以完成此任务。
在2012年之前的SQL Server中,您需要执行以下操作:
SELECT value - (
SELECT TOP 1 value
FROM mytable m2
WHERE m2.col1 < m1.col1 OR (m2.col1 = m1.col1 AND m2.pk < m1.pk)
ORDER BY
col1, pk
)
FROM mytable m1
ORDER BY
col1, pk
,COL1
您在此排序的列在哪里。
启用索引(COL1, PK)
将大大改善此查询。
WITH CTE AS (
SELECT
rownum = ROW_NUMBER() OVER (ORDER BY columns_to_order_by),
value
FROM table
)
SELECT
curr.value - prev.value
FROM CTE cur
INNER JOIN CTE prev on prev.rownum = cur.rownum - 1
select t2.col from (
select col,MAX(ID) id from
(
select ROW_NUMBER() over(PARTITION by col order by col) id ,col from testtab t1) as t1
group by col) as t2