Самый простой способ заполнить временную таблицу датами между и двумя параметрами даты
Каков самый простой способ заполнить временную таблицу датами, включая и между двумя параметрами даты. Мне нужен только первый день месяца.
Так, например, если @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
Ответы
Ответ 1
Это работает, даже если @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)
Ответ 2
declare @StartDate date = '2014-01-01';
declare @EndDate date = '2014-05-05';
;WITH cte AS (
SELECT @StartDate AS myDate
UNION ALL
SELECT DATEADD(day,1,myDate) as myDate
FROM cte
WHERE DATEADD(day,1,myDate) <= @EndDate
)
SELECT myDate
FROM cte
OPTION (MAXRECURSION 0)
Ответ 3
declare @StartDate datetime
declare @EndDate datetime
select @StartDate = '2011-01-01' , @EndDate = '2011-08-01'
select @StartDate= @StartDate-(DATEPART(DD,@StartDate)-1)
declare @temp table
(
TheDate datetime
)
while (@StartDate<[email protected])
begin
insert into @temp
values (@StartDate )
select @StartDate=DATEADD(MM,1,@StartDate)
end
select * from @temp
Работает, даже если @StartDate не является первым днем месяца, возвращаясь к начальному дню месяца StartDate
Ответ 4
это проверено в SQL 2008 R2
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
...
Ответ 5
Решение:
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
Ответ 6
Интересно, что быстрее создавать из перечислимых данных эту статью.
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;
На моей машине она на 60% быстрее с большими диапазонами дат. Метод рекурсии может заселить данные за 2000 лет примерно за 3 секунды, хотя и выглядит намного приятнее, поэтому я не рекомендую этот метод только для увеличения количества дней.
Ответ 7
Исправление для нулевых дат:
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
Ответ 8
CREATE TABLE #t (d DATE)
INSERT INTO #t SELECT GETDATE()
GO
INSERT #t SELECT DATEADD(DAY, -1, MIN(d)) FROM #t
GO 10