SELECT YMD,Value FROM Table
YMD Value
2014-01-01 100
2014-02-01 200
2014-03-01 300
2014-04-01 250
我想使用标量或表函数来获取上个月的值:
选择YMD,值,函数(YMD)作为prev1month FROM Table
YMD Value prev1month
2014-01-01 100 NULL
2014-02-01 200 100
2014-03-01 300 200
2014-04-01 250 300
让我们再添加一个条件:
选择YMD,值,函数(YMD)作为prev1month FROM Table
YMD Value prev1month prev1year
2013-01-01 50 NULL
2014-01-01 100 NULL 50
2014-02-01 200 100
2014-03-01 300 200
2014-04-01 250 300
我尝试过以下操作,但在以后的计算中遇到错误:
SELECT YMD, Value
FROM TABLE as t1
INNER JOIN TABLE 2 as t2
on t2.YMD = DATEADD(m,-1, t1.YMD)
有什么建议吗?
我正在使用SQL 2008 R2
答案 0 :(得分:2)
SQL标准具有执行此操作的lag()
功能。您还可以使用相关子查询编写查询。这需要从子查询中获取一行。这是一种适用于使用top
的数据库的方法:
select ymd, value,
(select top 1 value
from table t2
where t2.ymd < t.ymd
order by t2.ymd desc
) as prev_value
from table t1;
使用lag()
,它将是:
select ymd, value, lag(value) over (order by ymd) as prev_value
from table t;
这适用于SQL Server 2012 +。
答案 1 :(得分:2)
如果您正在使用MS SQL Server 2012+,则可以使用LAG()
窗口函数访问集合中的上一行:
SELECT YMD, Value, LAG(value) OVER (ORDER BY YMD) as prev1month FROM Table
其他一些RDBMS也提供相同的功能(延迟)。
编辑:由于您使用旧版本而不支持延迟,因此您必须使用其他方法,例如Gordon Linoff所描述的方法。
答案 2 :(得分:0)
select t.*,Prev.Value
from Table t
Outer Apply (Select top 1 Value
From Table P
Where P.Dt < t.Dt
Order by P.Dt Desc) Prev
答案 3 :(得分:0)
使用Left Join
执行此操作的另一种方法。这应该来自 SQL SERVER 2005+
CREATE TABLE #test
(YMD DATE,Value INT)
INSERT #test
VALUES( '2014-01-01',100 ),
('2014-02-01',200 ),
('2014-03-01',300 ),
('2014-04-01',250 );
WITH cte
AS (SELECT Row_number()OVER (ORDER BY ymd) Rn,
*
FROM #test)
SELECT a.YMD,
a.value,
b.value As Prev_Value
FROM cte a
LEFT JOIN cte b
ON a.Rn = b.Rn + 1
<强> 结果 强>
+-----------+-------+-------------+
| YMD | value | Prev_Value |
+-----------+-------+-------------+
|2014-01-01 | 100 | NULL |
|2014-02-01 | 200 | 100 |
|2014-03-01 | 300 | 200 |
|2014-04-01 | 250 | 300 |
+-----------+-------+-------------+