Как найти все дни первой недели (дни до первого воскресенья) месяца (дата указана) на сервере SQL? - PullRequest
1 голос
/ 29 апреля 2020

Я хочу найти все даты первой недели (дней до первого воскресенья), когда вам будет предоставлена ​​любая дата этого месяца.

Пример 1

Заданная дата:

2020-04-29

Ожидаемый результат выбранного запроса:

The first week of April 2020
-----------------------------------------------------
2020-04-01
2020-04-02
2020-04-03
2020-04-04
2020-04-05

Пример 2

Указанная дата:

2020-03-29

Ожидаемый результат выбранного запроса:

The first week of March 2020
-----------------------------------------------------
2020-03-01

Ответы [ 5 ]

0 голосов
/ 29 апреля 2020
CREATE OR ALTER FUNCTION F_FIRST_WEEKDATES (@A_DATE DATETIME2)
RETURNS @T TABLE (D DATE)
AS
BEGIN
DECLARE @D DATE = DATEFROMPARTS(YEAR(@A_DATE), MONTH(@A_DATE), 1), @N TINYINT = 1;
WHILE @N < 8 
BEGIN
   INSERT INTO @T VALUES (@D);
   SELECT @D = DATEADD(day, 1, @D), @N+=1;
   IF DATEPART(weekday, @D) = 1
      BREAK
END
RETURN;
END;
GO
0 голосов
/ 29 апреля 2020

Если вы хотите, чтобы все дни были до первого понедельника месяца, то вы можете использовать рекурсивный CTE:

with dates as (
     select dateadd(day, 1, eomonth('2020-04-29', -1)) as dte
     union all
     select dateadd(day, 1, dte)
     from dates 
     where datename(weekday, dte) <> 'Sunday'
)
select *, datename(weekday, dte)
from dates;

Это предполагает, что вам нужно 7 дней, когда неделя начинается в понедельник (хотя легко настраивается для обработки, чтобы не возвращать строки.

Здесь - это db <> скрипка.

0 голосов
/ 29 апреля 2020

Вам необходимо создать функцию, которая возвращает таблицу, например:

CREATE OR ALTER FUNCTION F_FIRST_N_WEEKDATES (@A_DATE DATETIME2, @N TINYINT)
RETURNS @T TABLE (D DATE)
AS
BEGIN
DECLARE @D DATE = DATEFROMPARTS(YEAR(@A_DATE), MONTH(@A_DATE), 1);
WHILE @N > 0
BEGIN
   INSERT INTO @T VALUES (@D);
   SELECT @D = DATEADD(day, 1, @D), @N-=1;
END
RETURN;
END;
GO

Пример:

SELECT *
FROM   dbo.F_FIRST_N_WEEKDATES('2020-04-29', 5)

give:

D
----------
2020-04-01
2020-04-02
2020-04-03
2020-04-04
2020-04-05
0 голосов
/ 29 апреля 2020

Вы можете просто использовать функцию while для распечатки дат.

Для получения результатов в одном операторе выбора. Вы можете вставить значения даты во временную таблицу

DECLARE @counter int = 1;
DECLARE @date date = '2020-04-29'

WHILE @counter <= 7
BEGIN
    select datefromparts(year(@date), month(@date), @counter); 
    SET @counter = @counter + 1;
END
0 голосов
/ 29 апреля 2020

Вы можете использовать рекурсивный подход:

with r_cte as (
     select dateadd(day, 1,  eomonth('2020-04-29', -1)) as start_dt, dateadd(day, 5, convert(date, EOMONTH('2020-04-29', -1))) as first_wk
     union all
     select dateadd(day, 1, start_dt), first_wk
     from r_cte 
     where start_dt < first_wk
)
select start_dt as first_week
from r_cte;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...