我有一些我想要计算的日期,目前在几个子查询中完成。每个后续子查询在其计算中使用上一个查询的结果(日期)。 E.g。
DECLARE @Date DATE = '20170101'
SELECT @foo1 = (SELECT TOP 1 dbo.DateFunction(DateField)
FROM [DateTable]
WHERE DateField <= @Date
ORDER BY DateField DESC)
SELECT @foo2 = (SELECT TOP 1 dbo.DateFunction(DateField)
FROM [DateTable]
WHERE DateField <= @foo1
ORDER BY DateField DESC)
....
SELECT @fooN = (SELECT TOP 1 dbo.DateFunction(DateField)
FROM [DateTable]
WHERE DateField <= @fooNMinus1
ORDER BY DateField DESC)
是否有可能(可能使用CTE)进行递归查询以达到指定次数?
答案 0 :(得分:0)
几周总是7天,所以你可以得到第一个,然后再加7天。如果是这样的话:
WITH dates as (
SELECT MAX(dbo.DateFunction(DateField)) as dte, 1 as counter
FROM [DateTable]
WHERE DateField <= @Date
UNION ALL
SELECT DATEADD(DAY, 7, dte), counter + 1
FROM dates
WHERE counter < @n
)
SELECT dte
FROM dates;
答案 1 :(得分:0)
您可以使用下面的小计数表
Declare @d1 date = '2017-01-01'
Declare @d2 date = '2017-12-31'
select top (datediff(day, @d1, @d2)+1) dt = DateAdd(day, Row_Number() over (order by (Select NULL))-1, @d1)
from master..spt_values s1, master..spt_values s2
或自定义计数表
;with num as
( select * from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) v(n) )
, n1 as (select n1.* from num n1, num n2, num n3, num n4) --numbers generation
select top (datediff(day, @d1, @d2)+1) dt = DateAdd(day, Row_Number() over (order by (Select NULL))-1, @d1)
from n1
答案 2 :(得分:0)
是的,您可以使用递归查询。由于递归部分中不允许使用top和聚合,因此可以使用row_number()函数。
Declare @date date = cast(getdate() as date), @n int = 10
declare @DateTable table (DateField date)
insert into @DateTable values ('2017-05-01'),('2017-05-02'),('2017-05-03'),('2017-05-04'),('2017-05-05'),('2017-05-06'),('2017-05-07'),('2017-05-08'),('2017-05-09'),('2017-05-10'),
('2017-05-11'),('2017-05-12'),('2017-05-13'),('2017-05-14'),('2017-05-15'),('2017-05-16'),('2017-05-17'),('2017-05-18'),('2017-05-19'),('2017-05-20')
;with date_rte as (
select top 1 dbo.DateFunction(DateField) datefield, 0 recursions, cast(1 as bigint) rn
from @dateTable
where datefield <= @date
order by datefield desc
union all
select dbo.DateFunction(DateField), recursions+1, ROW_NUMBER() over (order by d.datefield desc)
from @datetable d
join date_rte r on d.DateField <= r.datefield
where recursions < @n and rn = 1
)
select datefield
from date_rte
where rn=1 and recursions = @n