Sql 使用介于2个日期参数之间且包含2个日期参数的日期填充临时表的最简单方法
用包含两个日期参数的日期填充临时表的最简单方法是什么。我只需要每月的第一天 例如,如果@StartDate='2011-01-01'和@EndDate='2011-08-01' 那我要把这个放回桌上Sql 使用介于2个日期参数之间且包含2个日期参数的日期填充临时表的最简单方法,sql,sql-server-2005,tsql,Sql,Sql Server 2005,Tsql,用包含两个日期参数的日期填充临时表的最简单方法是什么。我只需要每月的第一天 例如,如果@StartDate='2011-01-01'和@EndDate='2011-08-01' 那我要把这个放回桌上 2011-01-01 2011-02-01 2011-03-01 2011-04-01 2011-05-01 2011-06-01 2011-07-01 2011-08-01 即使@StartDate不是一个月的第一天,也可以通过返回到StartDate月的第一天来工作解决方案: DECLARE
2011-01-01
2011-02-01
2011-03-01
2011-04-01
2011-05-01
2011-06-01
2011-07-01
2011-08-01
即使@StartDate不是一个月的第一天,也可以通过返回到StartDate月的第一天来工作解决方案:
DECLARE @StartDate DATETIME
,@EndDate DATETIME;
SELECT @StartDate = '20110105'
,@EndDate = '20110815';
SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, DATEADD(MONTH, v.number, @StartDate)), 0) AS FirstDay
--or Andriy M suggestion:
--SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, @StartDate) + v.number, 0) AS FirstDay
INTO #Results
FROM master.dbo.spt_values v
WHERE v.type = 'P'
AND DATEDIFF(MONTH, @StartDate, @EndDate) >= v.number;
SELECT *
FROM #Results;
DROP TABLE #Results;
结果:
FirstDay
-----------------------
2011-01-01 00:00:00.000
2011-02-01 00:00:00.000
2011-03-01 00:00:00.000
2011-04-01 00:00:00.000
2011-05-01 00:00:00.000
2011-06-01 00:00:00.000
2011-07-01 00:00:00.000
2011-08-01 00:00:00.000
即使@StartDate不是一个月的第一天,这也有效。我假设如果不是月初,你想从下个月的第一个月开始。否则,请拆下+1:
;WITH cte AS (
SELECT CASE WHEN DATEPART(Day,@StartDate) = 1 THEN @StartDate
ELSE DATEADD(Month,DATEDIFF(Month,0,@StartDate)+1,0) END AS myDate
UNION ALL
SELECT DATEADD(Month,1,myDate)
FROM cte
WHERE DATEADD(Month,1,myDate) <= @EndDate
)
SELECT myDate
FROM cte
OPTION (MAXRECURSION 0)
这在SQL2008R2中进行了测试
Declare @StartDate datetime = '2015-03-01'
Declare @EndDate datetime = '2015-03-31'
declare @temp Table
(
DayDate datetime
);
WHILE @StartDate <= @EndDate
begin
INSERT INTO @temp (DayDate) VALUES (@StartDate);
SET @StartDate = Dateadd(Day,1, @StartDate);
end ;
select * from @temp
有趣的是,根据枚举数据创建数据的速度更快
在我的机器上,使用大的日期范围,速度大约快60%。不过,递归方法可以在大约3秒钟内填充2000年的数据,而且看起来更好,所以我不建议仅在递增天数时使用这种方法。空日期更正:
IF OBJECT_ID('tempdb..#dim') IS NOT NULL
DROP TABLE #dim
CREATE TABLE #dim ([date] DATE)
if not @Begin_Date is null and not @End_Date is null
begin
INSERT #dim([date])
SELECT d
FROM(
SELECT
d = DATEADD(DAY, rn - 1, @Begin_Date)
FROM
(
SELECT TOP (DATEDIFF(DAY, @Begin_Date, @End_Date))
rn = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM
sys.all_objects AS s1
CROSS JOIN
sys.all_objects AS s2
ORDER BY
s1.[object_id]
) AS x
) AS y;
end
+1,您还可以执行DATEDIFFMONTH,0,@StartDate+v.number,而不是DATEDIFFMONTH,0,DATEADDMONTH,v.number,@StartDate。在单个记录中按原样运行示例的结果。我遗漏了什么?@ElanHasson,你是否在不同的月份设置了StartDate和EndDate?如果StartDate不是一个月的第一个月,则使用下个月的第一个月。这就是我遗漏的。我用了尼廷的解决方案,因为它最近被投票通过了。对于SQL 2012或更高版本,ELSE表达式应替换为:ELSE DATEADDDay,1,EOMONTH@StartDate以MyDate结尾,交叉连接技巧很酷。与其他解决方案相比,For可以立即执行数千行。
Declare @StartDate datetime = '2015-03-01'
Declare @EndDate datetime = '2015-03-31'
declare @temp Table
(
DayDate datetime
);
WHILE @StartDate <= @EndDate
begin
INSERT INTO @temp (DayDate) VALUES (@StartDate);
SET @StartDate = Dateadd(Day,1, @StartDate);
end ;
select * from @temp
DayDate
-----------------------
2015-03-01 00:00:00.000
2015-03-02 00:00:00.000
2015-03-03 00:00:00.000
2015-03-04 00:00:00.000
...
DECLARE @StartDate DATE = '10001201';
DECLARE @EndDate DATE = '20000101';
DECLARE @dim TABLE ([date] DATE)
INSERT @dim([date])
SELECT d
FROM
(
SELECT
d = DATEADD(DAY, rn - 1, @StartDate)
FROM
(
SELECT TOP (DATEDIFF(DAY, @StartDate, @EndDate))
rn = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM
sys.all_objects AS s1
CROSS JOIN
sys.all_objects AS s2
ORDER BY
s1.[object_id]
) AS x
) AS y;
IF OBJECT_ID('tempdb..#dim') IS NOT NULL
DROP TABLE #dim
CREATE TABLE #dim ([date] DATE)
if not @Begin_Date is null and not @End_Date is null
begin
INSERT #dim([date])
SELECT d
FROM(
SELECT
d = DATEADD(DAY, rn - 1, @Begin_Date)
FROM
(
SELECT TOP (DATEDIFF(DAY, @Begin_Date, @End_Date))
rn = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM
sys.all_objects AS s1
CROSS JOIN
sys.all_objects AS s2
ORDER BY
s1.[object_id]
) AS x
) AS y;
end
CREATE TABLE #t (d DATE)
INSERT INTO #t SELECT GETDATE()
GO
INSERT #t SELECT DATEADD(DAY, -1, MIN(d)) FROM #t
GO 10