Sql server 2008 在SQLServer2008中如何在一条SQL语句中获取两天价格的返回值
我有这样的桌子Sql server 2008 在SQLServer2008中如何在一条SQL语句中获取两天价格的返回值,sql-server-2008,Sql Server 2008,我有这样的桌子 create table #tmp(dt Date, price float) insert into #tmp values('01-Jan-2013', 55.60) insert into #tmp values('02-Jan-2013', 50.22) insert into #tmp values('03-Jan-2013', 52.00) insert into #tmp values('04-Jan-2013', 55.90) insert into #tmp
create table #tmp(dt Date, price float)
insert into #tmp values('01-Jan-2013', 55.60)
insert into #tmp values('02-Jan-2013', 50.22)
insert into #tmp values('03-Jan-2013', 52.00)
insert into #tmp values('04-Jan-2013', 55.90)
insert into #tmp values('05-Jan-2013', 60.60)
select * from #tmp order by dt
drop table #tmp
我想在一条SQL语句中得到两天价格的返回值。计算很简单,例如,如果我想计算2013年1月2日的返回值,则为:2013年1月2日的价格值除以2013年1月1日的价格值和-1
我想要像下面这样的输出
dt |price |Return
-------------------------------------
01-Jan-2013 |55.6 |0
-------------------------------------
02-Jan-2013 |50.22 |-0.09676259
-------------------------------------
03-Jan-2013 |52 |0.035444046
-------------------------------------
04-Jan-2013 |55.9 |0.075
-------------------------------------
05-Jan-2013 |60.6 |0.084078712
如何在单个SQL语句中获得结果?似乎相当简单:
select
t1.dt,t1.price,
(t1.price/t2.price)-1 as [return]
from
#tmp t1
left join
#tmp t2
on t1.dt = DATEADD(day,1,t2.dt)
请注意,这当前为第一行返回NULL,而不是0,但如果需要,可以通过将计算包装在COALESCE…,0中来修复。还要注意,这假设每天都有值。如果不是这样,我们需要一个更复杂的查询
如果您需要考虑到缺少日期,您将不得不为速度明显较慢的查询付出代价:
select
t1.dt,t1.price,
(t1.price/t2.price)-1 as [return]
from
#tmp t1
left join
#tmp t2
on t2.dt < t1.dt
left join
#tmp t3
on t3.dt < t1.dt and
t2.dt < t3.dt
where
t3.dt is null
暂时忽略所有这些行都来自同一个表,我们基本上说的是将t1行与t1行之前出现的任何t2行配对。然后,我们尝试通过t3查找出现在t2行之后但仍在t1行之前的任何行。只有在我们找不到t3行的情况下,t2行才是我们想要的—它可能是最新的前一行。抱歉,如果这听起来很费解,请始终寻找更好的方法来解释这一点。在某些日期中,如果缺少日期,它会返回错误的值,您在这里已经提到,这些值适用于每天。我可以得到一个复杂的查询,其中日期是连续的,但有些日期丢失。谢谢