use*_*557 33 sql sql-server cursor
如何获取两个日期之间的日期?
我有一个变量@MAXDATE
,它存储表中的最大日期.现在我想得到之间的所有日期@Maxdate
,GETDATE()
并希望将这些日期存储在游标中.
到目前为止,我做了如下:
;with GetDates As
(
select DATEADD(day,1,@maxDate) as TheDate
UNION ALL
select DATEADD(day,1, TheDate) from GetDates
where TheDate < GETDATE()
)
Run Code Online (Sandbox Code Playgroud)
这是完美的工作,但当我试图将这些值存储在游标中时
SET @DateCurSor=CURSOR FOR
SELECT TheDate
FROM GetDates
Run Code Online (Sandbox Code Playgroud)
编译错误
关键字"SET"附近的语法不正确.
怎么解决这个问题.
提前致谢
Gar*_*thD 56
我的第一个建议是使用您的日历表,如果您没有,请创建一个.它们非常有用.您的查询就像下面这样简单:
DECLARE @MinDate DATE = '20140101',
@MaxDate DATE = '20140106';
SELECT Date
FROM dbo.Calendar
WHERE Date >= @MinDate
AND Date < @MaxDate;
Run Code Online (Sandbox Code Playgroud)
如果您不想或不能创建日历表,您仍然可以在没有递归CTE的情况下即时执行此操作:
DECLARE @MinDate DATE = '20140101',
@MaxDate DATE = '20140106';
SELECT TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate)
FROM sys.all_objects a
CROSS JOIN sys.all_objects b;
Run Code Online (Sandbox Code Playgroud)
如需进一步阅读,请参阅:
关于然后在光标中使用这个日期序列,我真的建议你找到另一种方法.通常有基于集合的替代方案,其性能会更好.
所以你的数据:
date | it_cd | qty
24-04-14 | i-1 | 10
26-04-14 | i-1 | 20
Run Code Online (Sandbox Code Playgroud)
要获得2014年4月28日的数量(我收集的是您的要求),您实际上并不需要上述任何一项,您可以简单地使用:
SELECT TOP 1 date, it_cd, qty
FROM T
WHERE it_cd = 'i-1'
AND Date <= '20140428'
ORDER BY Date DESC;
Run Code Online (Sandbox Code Playgroud)
如果您不希望它用于特定项目:
SELECT date, it_cd, qty
FROM ( SELECT date,
it_cd,
qty,
RowNumber = ROW_NUMBER() OVER(PARTITION BY ic_id
ORDER BY date DESC)
FROM T
WHERE Date <= '20140428'
) T
WHERE RowNumber = 1;
Run Code Online (Sandbox Code Playgroud)
Anv*_*esh 22
您可以使用此脚本查找两个日期之间的日期.参考本文:
DECLARE @StartDateTime DATETIME
DECLARE @EndDateTime DATETIME
SET @StartDateTime = '2015-01-01'
SET @EndDateTime = '2015-01-12';
WITH DateRange(DateData) AS
(
SELECT @StartDateTime as Date
UNION ALL
SELECT DATEADD(d,1,DateData)
FROM DateRange
WHERE DateData < @EndDateTime
)
SELECT DateData
FROM DateRange
OPTION (MAXRECURSION 0)
GO
Run Code Online (Sandbox Code Playgroud)
只是说......这是一个更简单的方法:
declare @sdate date = '2017-06-25'
, @edate date = '2017-07-24';
with dates_CTE (date) as (
select @sdate
Union ALL
select DATEADD(day, 1, date)
from dates_CTE
where date < @edate
)
select *
from dates_CTE;
Run Code Online (Sandbox Code Playgroud)
小智 5
轻松创建一个表值函数,它将返回一个包含所有日期的表。 以字符串形式输入日期 您可以以您喜欢的格式自定义日期 '01/01/2017' 或 '01-01-2017' 字符串格式 (103,126 ...)
尝试这个
CREATE FUNCTION [dbo].[DateRange_To_Table] ( @minDate_Str NVARCHAR(30), @maxDate_Str NVARCHAR(30))
RETURNS @Result TABLE(DateString NVARCHAR(30) NOT NULL, DateNameString NVARCHAR(30) NOT NULL)
AS
begin
DECLARE @minDate DATETIME, @maxDate DATETIME
SET @minDate = CONVERT(Datetime, @minDate_Str,103)
SET @maxDate = CONVERT(Datetime, @maxDate_Str,103)
INSERT INTO @Result(DateString, DateNameString )
SELECT CONVERT(NVARCHAR(10),@minDate,103), CONVERT(NVARCHAR(30),DATENAME(dw,@minDate))
WHILE @maxDate > @minDate
BEGIN
SET @minDate = (SELECT DATEADD(dd,1,@minDate))
INSERT INTO @Result(DateString, DateNameString )
SELECT CONVERT(NVARCHAR(10),@minDate,103), CONVERT(NVARCHAR(30),DATENAME(dw,@minDate))
END
return
end
Run Code Online (Sandbox Code Playgroud)
要执行该功能,请执行以下操作:
SELECT * FROM dbo.DateRange_To_Table ('01/01/2017','31/01/2017')
Run Code Online (Sandbox Code Playgroud)
输出将是
01/01/2017 Sunday
02/01/2017 Monday
03/01/2017 Tuesday
04/01/2017 Wednesday
05/01/2017 Thursday
06/01/2017 Friday
07/01/2017 Saturday
08/01/2017 Sunday
09/01/2017 Monday
10/01/2017 Tuesday
11/01/2017 Wednesday
12/01/2017 Thursday
13/01/2017 Friday
14/01/2017 Saturday
15/01/2017 Sunday
16/01/2017 Monday
17/01/2017 Tuesday
18/01/2017 Wednesday
19/01/2017 Thursday
20/01/2017 Friday
21/01/2017 Saturday
22/01/2017 Sunday
23/01/2017 Monday
24/01/2017 Tuesday
25/01/2017 Wednesday
26/01/2017 Thursday
27/01/2017 Friday
28/01/2017 Saturday
29/01/2017 Sunday
30/01/2017 Monday
31/01/2017 Tuesday
Run Code Online (Sandbox Code Playgroud)