binu.emiliya Ответов: 3

Создайте диапазон дат между двумя датами в SQL server


У меня есть таблица, как показано ниже

ACADEMIC_TERM	ACADEMIC_YEAR	      START_DATE	            END_DATE
FALL	                2014          2014-10-12 00:00:00.000	2015-01-22 00:00:00.000
FALL	                2015	      2015-09-13 00:00:00.000	2016-01-05 00:00:00.000
SPRG	                2015	      2015-02-15 00:00:00.000	2015-05-28 00:00:00.000


Я хочу расширить диапазон дат

как показано ниже

DATE            ACADEMIC_YEAR       ACADEMIC_TERM
     12-10-2014      2014                FALL
     13-10-2014      2014                FALL
     ----------      ------              ----
     ----------      ------              ----
     ----------      ------              ----
     15-02-2015      2015                SPRG
     16-02-2015      2015                SPRG
     ----------      ------              ----
     ----------      ------              ----
     13-09-2015      2015                FALL
     ----------      ------              ----
     ----------      ------              ----
     ----------      ------              ----


даты должны создаваться автоматически с датой начала и окончания каждого семестра. Как я могу это сделать?

Что я уже пробовал:

Я создал даты между датой начала первого семестра и getdate() в качестве последней даты, но он не может определить, какой термин является датой. Для года я могу просто взять Datepart(дата)

3 Ответов

Рейтинг:
23

Maciej Los

Я бы рекомендовал использовать КТОС[^], что - вкратце - означает: рекурсивный запрос.

Взгляните на пример:

DECLARE @tmp TABLE(ACADEMIC_TERM VARCHAR(50), ACADEMIC_YEAR INT, [START_DATE] DATETIME, END_DATE DATETIME)

INSERT INTO @tmp (ACADEMIC_TERM, ACADEMIC_YEAR, [START_DATE], END_DATE)
VALUES('FALL', 2014, '2014-10-12 00:00:00.000', '2015-01-22 00:00:00.000'),
('FALL', 2015, '2015-09-13 00:00:00.000', '2016-01-05 00:00:00.000'),
('SPRG', 2015, '2015-02-15 00:00:00.000', '2015-05-28 00:00:00.000')

;WITH CTE AS
(
	--initial query
	SELECT ROW_NUMBER() OVER(ORDER BY ACADEMIC_YEAR) AS RowNo, 1 AS IterationID, ACADEMIC_TERM, ACADEMIC_YEAR, [START_DATE] AS CurrDate, END_DATE
	FROM @tmp 
	--recursive part
	UNION ALL
	SELECT RowNo, IterationID +1, ACADEMIC_TERM, ACADEMIC_YEAR, DATEADD(dd, 1, CurrDate)  AS CurrDate, END_DATE
	FROM CTE
	WHERE DATEADD(dd, IterationID, CurrDate)<=END_DATE 
)
SELECT CurrDate, ACADEMIC_TERM, ACADEMIC_YEAR 
FROM CTE 
ORDER BY RowNo, IterationID



Для получения дополнительной информации, пожалуйста, смотрите: DATEADD (Transact-SQL) | Microsoft Docs[^]

Удачи вам!


binu.emiliya

Это прекрасно работает большое вам спасибо за вашу помощь

Maciej Los

Всегда пожалуйста.

binu.emiliya

Дорогой Мацей Лос,

Я использую этот код сейчас, но он не возвращает данные за прошлый месяц, скажем, пример Весна 2017 последняя дата-31 декабря-2107, но код получает данные только до ноября.

Maciej Los

Это должно работать нормально, даже для 2017-12-31 годов. Пожалуйста, проверьте, если дата находится в правильном формате.

binu.emiliya

'2014-10-13 00:00:00.000' это формат даты, который я использую, и я храню этот код в представлении, поэтому я использую ТОП-100 процентов в этом коде. Но я не получаю даты последнего месяца каждого семестра.

Спасибо за ваше время

Maciej Los

Ну, я понятия не имею, почему ты не получаешь даты последнего месяца каждого семестра... Обратите внимание, что у меня нет доступа к вашему жесткому диску или SQL-серверу. Как вы знаете, приведенный выше CTE-запрос отлично работает для выборочных данных, так что... is также должен работать для реальных данных.

binu.emiliya

Хорошо, спасибо!

Member 4280314

Где в рекурсивной части должно быть следующим образом, чтобы вернуть все даты:

Где DATEADD(dd, 1, CurrDate)<=END_DATE

Рейтинг:
2

kirthiga S

Вы можете создать дату между диапазонами с помощью этого запроса

Declare @StartDay datetime, @EndDay datetime
Set @StartDay='2018-01-01'
Set @EndDay='2018-12-31'

;with cte(Date) as 
(
select @StartDay
union all
select Date+1 from cte where Date < @EndDay
)
select Date,DATENAME(W,Date)Day from cte option (MAXRECURSION 400)


Maciej Los

Это решение полезно только частично. Взгляните на диапазоны дат... Они совсем другие. Это не просто дата-от до даты-до, но набор из них. Пожалуйста, смотрите мой ответ.

binu.emiliya

Спасибо тебе, Критига. Это я уже сделал

Рейтинг:
15

MadMyche

Я воссоздал вашу таблицу как @AcadmicDates и заселил ее как таковую, как показано ниже

DECLARE @AcademicDates TABLE (
     AcademicTerm  VARCHAR(6)  NULL,
     AcademicYear  INT         NULL,
     StartDate     DATE        NULL,
     EndDate       DATE        NULL
)

INSERT  @AcademicDates 
VALUES  ('Fall',    2014, '10/12/2014', '01/22/2015')
,       ('Fall',    2015, '09/13/2015', '01/05/2016')
,       ('Spring',  2015, '02/15/2015', '05/28/2015')


Ваша часть диапазона "расширение даты" на самом деле представляет собой простой запрос:
SELECT  AcademicYear, AcademicTerm
FROM    @AcademicDates
WHERE   '10/12/2014' BETWEEN StartDate AND EndDate


И может быть использован для заполнения вторичной таблицы
DECLARE	@DateToAcademicDate TABLE (
     DateToCheck   DATE        NULL,
     AcademicYear  INT         NULL,
     AcademicTerm  VARCHAR(6)  NULL
)

DECLARE @RangeDate DATE = '10/12/2014'
WHILE (@RangeDate <= '01/05/2016') BEGIN 
  IF EXISTS(SELECT 1 FROM @AcademicDates WHERE @RangeDate BETWEEN StartDate AND EndDate) BEGIN
    INSERT  @DateToAcademicDate 
    SELECT  @RangeDate, AcademicYear, AcademicTerm
    FROM    @AcademicDates
    WHERE   @RangeDate BETWEEN StartDate AND EndDate
  END
  SET @RangeDate = DATEADD(dd, 1, @RangeDate)
END


Который вернет следующее
DateToCheck AcademicYear AcademicTerm
----------- ------------ ------------
2014-10-12  2014         Fall
...         2014         Fall
2015-01-22  2014         Fall
2015-02-15  2015         Spring
...         2015         Spring
2015-05-28  2015         Spring
2015-09-13  2015         Fall
...         2015         Fall
2016-01-05  2015         Fall


Maciej Los

Выглядит многообещающе...
5ed!

binu.emiliya

Это тоже прекрасно работает.большое вам спасибо за ваше время

binu.emiliya

Уважаемые MadMyche,
Есть ли какой-нибудь способ использовать этот код в представлении?

MadMyche

Он может быть развит в нечто подобное; однако вам нужно будет точно знать, что вы ищете и какой тип инфраструктуры БД вы собираетесь поддерживать для поддержки этого