SQL Server 2008 Создайте серию дат
Я пытаюсь создать таблицу с серией дат в ней.
У меня есть указанное время начала и дата окончания даты (дата окончания даты - конец последовательности), я добавляю временной интервал ~ (это может варьироваться) до даты начала отсчета в секундах, и это дает мне время окончания,
Следующая последовательность использует время окончания в качестве стартового значения и добавляет к нему временной интервал в секундах. Чтобы продемонстрировать выход, мне нужно. Есть ли быстрый способ создать такую таблицу, отличную от использования большого количества вставки в команды?, Я действительно тупой
StartTime Endtime Duration
2011-07-20 11:00:33 2011-07-20 11:09:47 554
2011-07-20 11:09:47 2011-07-20 11:19:01 554
declare @StartTime datetime = '2011-07-20 11:00:33',
@EndTime datetime = '2011-07-20 15:37:34'
@Interval int = 554 -- this can be changed.
insert into tmp_IRange
values('2011-07-20 11:00:33', DATEADD(SECONDS, @Duration, 2011-07-20 11:00:33))
Это становится очень утомительным.. особенно когда время окончания даты 2011-07-20 15:37:34
есть много инструкций вставки, чтобы сделать: (
Ответы
Ответ 1
Используйте рекурсивный CTE
declare @StartTime datetime = '2011-07-20 11:00:33',
@EndTime datetime = '2011-07-20 15:37:34',
@Interval int = 554 -- this can be changed.
;WITH cSequence AS
(
SELECT
@StartTime AS StartRange,
DATEADD(SECOND, @Interval, @StartTime) AS EndRange
UNION ALL
SELECT
EndRange,
DATEADD(SECOND, @Interval, EndRange)
FROM cSequence
WHERE DATEADD(SECOND, @Interval, EndRange) < @EndTime
)
/* insert into tmp_IRange */
SELECT * FROM cSequence OPTION (MAXRECURSION 0);
Ответ 2
Этот будет давать отдельные диапазоны, но будет игнорировать ваше фактическое конечное время (поскольку он равен < @interval после последнего допустимого диапазона):
;WITH x AS
(
SELECT TOP (DATEDIFF(SECOND, @StartTime, @EndTime)/@Interval)
rn = ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.objects
)
-- INSERT INTO dbo.tmp_IRange
SELECT DATEADD(SECOND, @Interval * (rn-1), @StartTime),
DATEADD(SECOND, @Interval * rn, @StartTime)
FROM x;
Ответ 3
Это должно помочь вам начать. Вы можете адаптировать его к вашим конкретным потребностям. Как написано, он будет генерировать строку для каждого минутного приращения, начиная с текущей даты и времени.
DECLARE @BaseDate DateTime = GETDATE();
WITH DateTable (DateValue) AS (
SELECT @BaseDate DateValue
UNION ALL
SELECT DATEADD(Minute, 1, DateValue) DateValue
FROM DateTable
)
SELECT *
FROM DateTable
WHERE DateValue < DATEADD(Day, 1, GETDATE())
OPTION (MAXRECURSION 0);
Ответ 4
Здесь другое нерекурсивное решение на основе набора, в котором используется системная таблица под названием master..spt_values
?
DECLARE
@StartTime datetime = '2011-07-20 11:00:33',
@EndTime datetime = '2011-07-20 15:37:34',
@Interval int = 554;
SELECT
StartTime = DATEADD(SECOND, (number - 1) * @Interval, @StartTime),
EndTime = DATEADD(SECOND, (number - 0) * @Interval, @StartTime),
Duration = @Interval
FROM master..spt_values
WHERE type = 'P'
AND number BETWEEN 1 AND DATEDIFF(SECOND, @StartTime, @Endtime) / @Interval
UNION ALL
SELECT
DATEADD(SECOND, -Duration, EndTime),
EndTime,
Duration
FROM (
SELECT
EndTime = @EndTime,
Duration = DATEDIFF(SECOND, @StartTime, @Endtime) % @Interval
) s
WHERE Duration > 0
Первый SELECT создает набор строк, состоящий из коротких интервалов заданной длины, которые лежат в указанном диапазоне. При необходимости второй SELECT добавляет интервал между первым временем окончания последнего интервала SELECT и заданным временем окончания.
Подмножество master..spt_values
, которое особенно используется здесь (и может использоваться во многих подобных случаях), содержит список чисел от 0 до 2047. Это означает, что вы не сможете использовать это решение с этим если начальный интервал будет разделен на более 2047 коротких (эр) интервалов. Затем вы должны подумать о чем-то вроде таблица номеров.
Ответ 5
Надеюсь, что это поможет...
declare @StartTime datetime = '2011-07-20 11:00:33',
@EndTime datetime = '2011-07-20 11:00:33',
@Interval int = 554,
@LimitTime datetime = '2011-07-20 15:37:34'
WHILE @EndTime < @LimitTime
BEGIN
SELECT @EndTime = DATEADD(S, @Interval, @StartTime)
SELECT @StartTime, @EndTime
--INSERT INTO tmp_IRange VALUES(@StartTime, @EndTime)
SELECT @StartTime = @EndTime
END
Ответ 6
попробуйте этот код:
create table #T (date_begin datetime, date_end datetime)
declare @StartTime datetime = '2011-07-20 11:00:33',
@EndTime datetime = '2011-07-20 15:37:34',
@Interval int = 554 -- this can be changed.
while DATEADD(ss,@Interval,@StartTime)<[email protected]
begin
insert #T
select @StartTime, DATEADD(ss,@Interval,@StartTime)
set @StartTime = DATEADD(ss,@Interval,@StartTime)
end
select * from #T