wizy@2020 Ответов: 3

Как установить дату начала и окончания месяца на 25-е и 26-е соответственно для каждого года с помощью T-SQL


Мне нужно решить две проблемы. Один из них - изменить первый день недели на вторник, а другой-изменить конец месяца на 25-е и дату начала на 26-е с февраля по ноябрь.
Январь должен начинаться с 1 по 25 декабря, а декабрь-с 26 ноября по 31 декабря.

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

Мне удалось выяснить первую часть. Таким образом, меняем первую дату недели на вторник.

установить дату начала 2;

3 Ответов

Рейтинг:
0

Maciej Los

Я не уверен, что хорошо вас понимаю, но ... ..

Вы можете использовать КТОС[^] для таких требований:
[Изменить комментарий="После второго чтения"]

DECLARE @initstartdate DATE = '2020-01-01';
DECLARE @initenddate DATE = '2020-12-31';

;WITH CTE AS
(
	--initial query
	SELECT @initstartdate startdate, DATEADD(DD, 24, @initstartdate) enddate
	UNION ALL
	--recursive part
	SELECT DATEADD(DD, 1, enddate) startdate, CASE WHEN MONTH(DATEADD(MM, 1, enddate)) = 12 THEN @initenddate ELSE DATEADD(MM, 1, enddate) END
	FROM CTE 
	WHERE MONTH(enddate) < 12
)
SELECT *
FROM CTE


Результат:
2020-01-01	2020-01-25
2020-01-26	2020-02-25
2020-02-26	2020-03-25
2020-03-26	2020-04-25
2020-04-26	2020-05-25
2020-05-26	2020-06-25
2020-06-26	2020-07-25
2020-07-26	2020-08-25
2020-08-26	2020-09-25
2020-09-26	2020-10-25
2020-10-26	2020-11-25
2020-11-26	2020-12-31

[/КОНЕЦ РЕДАКТИРОВАНИЯ]


wizy@2020

Хороший Мацей.
Чего я действительно хочу добиться, так это получить следующие результаты
е.г

RecDate	        MonthNo
2020-01-01	1
...
2020-01-25	1
2020-01-26	2
...
2020-02-25	2
2020-02-26	3

up to

2020-12-31	12


У меня есть таблица с более чем 20000 записями, и я хочу в любой момент получить правильный номер месяца. Это должно быть в состоянии работать с любым годом.

Maciej Los

См. решение № 4.

Рейтинг:
0

MarcusCole6833

Мой немного более тяжелый код, но в любом случае вам придется делать это без установленного шаблона для каждого месяца.

declare @dateTable table ( id int identity(1,1), sDate date, eDate date)

declare @min int = 1 , @max int = 12
declare @sdate date = '2020-01-01'
declare @edate date = '2020-01-25'
declare @eDateTm datetime
declare @sDateTm datetime

while @min <= @max
begin 
if @min = 100
	begin
		break;
	end
	
	if @min > 1
	begin
		if month(@sdate) < 11
		begin
		set @eDateTm = dateAdd(MM, 1 , @sdate)
		set @eDateTm = dateAdd(dd, -1 , @eDateTm)
		set @edate = cast(@eDateTm as date)
		
		insert into @dateTable 
		select @sdate , @edate

		set @sDateTm = dateAdd(dd, +1 , @eDateTm)
		set @sdate = cast(@sDateTm as date)
		end
		else
		begin
			set @edate = '2020-12-31'
			insert into @dateTable 
			select @sdate , @edate
		end
	end
	else
	begin
		insert into @dateTable 
		select @sdate , @edate
		set @sDateTm = dateAdd(dd, +1 , @eDate)
		set @sdate = cast(@sDateTm as date)

	end
	set @min = @min + 1
	--select @min

end

select * from @dateTable


Рейтинг:
0

Maciej Los

wizy@2020 написал:

Хороший Мацей.
Чего я действительно хочу добиться, так это получить следующие результаты
е.г
RecDate MonthNo
2020-01-01 1
2020-01-02 1
...
2020-01-25 1
2020-01-26 2
...
2020-02-25 2
2020-02-26 3
...
up to
2020-12-31 12


У меня есть таблица с более чем 20000 записями, и я хочу в любой момент получить правильный номер месяца. Это должно быть в состоянии работать с любым годом.


Этот запрос должен произвести набор из - за потребностей ОП:
--initial range
DECLARE @initstartdate DATE = CAST('2019-01-01' AS DATE); --define initial start date
DECLARE @initenddate DATE = CAST('2020-12-31' AS DATE); --define initial end date
--declare and fill-in reference table to store fiscal year details
DECLARE @reftable TABLE(refdayfrom INT, refmonthfrom INT, refdayto INT, refmonthto INT, fiscalmonth INT)
INSERT INTO @reftable(refdayfrom, refmonthfrom, refdayto, refmonthto, fiscalmonth)
VALUES(1, 1, 25, 1, 1),
(26, 1, 25, 2, 2),
(26, 2, 25, 3, 3),
(26, 3, 25, 4, 4),
(26, 4, 25, 5, 5),
(26, 5, 25, 6, 6),
(26, 6, 25, 7, 7),
(26, 7, 25, 8, 8),
(26, 8, 25, 9, 9),
(26, 9, 25, 10, 10),
(26, 10, 25, 11, 11),
(26, 11, 31, 12, 12)

--get all dates between initial start date and end date
;WITH alldates AS
(
	SELECT @initstartdate RecDate
	UNION ALL
	SELECT DATEADD(DD, 1, RecDate) RecDate 
	FROM alldates
	WHERE DATEADD(DD, 1, RecDate)<=@initenddate 
),
--get fiscal year details for years between initial start date and end date
	dateranges AS
	(
		--initial query
		SELECT DATEFROMPARTS(YEAR(@initstartdate), refmonthfrom, refdayfrom ) startdate, DATEFROMPARTS(YEAR(@initstartdate), refmonthto, refdayto) enddate, fiscalmonth
		FROM @reftable
		UNION ALL
		----recursive part
		SELECT DATEFROMPARTS(YEAR(DATEADD(YY, 1, startdate)), MONTH(startdate), DAY(startdate)) startdate, 
			DATEFROMPARTS(YEAR(DATEADD(YY, 1, enddate)), MONTH(enddate), DAY(enddate)) enddate, fiscalmonth
		FROM dateranges 
		WHERE DATEADD(YY, 1, enddate)<= @initenddate 
	)
-- mix all together ;)
	SELECT ad.RecDate, dr.fiscalmonth MonthNo
	FROM alldates ad INNER JOIN dateranges dr ON ad.RecDate BETWEEN dr.startdate AND dr.enddate 
	ORDER BY RecDate
	OPTION (MAXRECURSION 0);


Вышеприведенный запрос производит (731 запись за 0,001 секунды):
RecDate	MonthNo
2019-01-01	1
up to
2020-12-31	12



Примечание: Вы можете создать справочную таблицу как физическую таблицу (а не переменную /тип таблицы/). Тогда вы сможете использовать его в запросе, не создавая и не заполняя переменную.