我试图在行之间获得日期差距(以天为单位)。 例如,我的数据按saleDate排序,如下所示:
ID | saleDate ID | gapInDays
10 | 1/1/2014 10 | 4 -- (5/1/2014 - 1/1/2014).Days
20 | 5/1/2014 20 | 2
30 | 7/1/2014 ====>>> 30 | 3
40 | 10/1/2014 40 | 7
50 | 17/1/2014 50 | 1 -- last row will always be 1
在代码中执行它并不是什么大问题,但因为行数很大(几百万)我试图在SP级别这样做。我假设我可以使用光标,但我知道它很慢。
任何解决方案都将受到高度赞赏。
皮尼。
答案 0 :(得分:2)
如果您使用的是SQL SERVER 2012 / Oracle / Postgres / DB2,则可以使用LEAD(),LAG()函数。
select ID,saleDate,LEAD(saleDate) over (order by saleDate) DateOfNextRow
,Isnull(Datediff(dd,saleDate,LEAD(saleDate) over (order by saleDate)),1) as gapInDays
from Order
对于SQL SERVER 2005/2008,您可以使用ROW_NUMBER()
等窗口函数。
答案 1 :(得分:1)
显然,您希望这可以在缺少LAG
和LEAD
窗口函数的SQL Azure上运行。
应该使用的一个解决方案是使用在日期列上应用的ROW_NUMBER
排名函数。 Azure支持ROW_NUMBER
,因此此代码应该有效:
select t1.id, isnull(datediff(day, t1.saledate, t2.saledate), 1) as gapInDays
from
(select id, saledate, rn = row_number() over (order by saledate, id) from gaps) t1
left join
(select id, saledate, rn = row_number() over (order by saledate, id) from gaps) t2
on t1.rn = t2.rn-1
如果你想要它稍微更紧凑(如果Azure支持我相信它的ctes)你可以将它作为一个公用表表达式来执行:
;with c as (
select id, saledate, r = row_number() over (order by saledate, id) from gaps
)
select c.id, isnull(datediff(day, c.saledate, c2.saledate), 1) as gapInDays
from c left join c c2 on c.r = c2.rn-1
在这些查询中,我按saledate对行进行了排序,如果不正确,则可能需要将其更改为order by id, saledate
,如果它是确定顺序的ID。
答案 2 :(得分:0)
如果您的ID是严格顺序的,您可以执行类似的操作
select
a.id, b.saleDate - a.saleDate
from
yourTable as a, yourTable as b
where
a.id = b.id-1
答案 3 :(得分:0)
如果数据库是SQL Server,那么以下查询应该有效。
WITH Sales AS
(
SELECT
*, ROW_NUMBER() OVER (ORDER BY SaleDate) AS RowNumber
FROM
TableName
)
SELECT
DATEDIFF(DAY, T1.SaleDate, T2.SaleDate)
FROM
Sales AS T1 INNER JOIN Sales AS T2
ON T1.RowNumber = T2.RowNumber - 1;