kirthiga S Ответов: 2

Как я могу получить вчерашние данные в SQL server с учетом выходных дней


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

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

--Вчера
select convert(varchar(8),GETDATE()-1,112)

CHill60

Там нет необходимости для преобразования дата - использование функции datepart если вы хотите, чтобы День ангела

kirthiga S

Мое требование заключается в том, как указать условия для понедельника третьей недели и других недель

CHill60

3-я неделя чего? В каком году? месяц?

kirthiga S

месяц

Richard MacCutchan

Проверьте, какой сегодня день и какая неделя, и соответственно скорректируйте свой запрос.

kirthiga S

Вот что как я могу это сделать

2 Ответов

Рейтинг:
9

kirthiga S

Спасибо всем. Наконец я нашел решение.

Declare @StartDate datetime,@EndDate datetime
set @EndDate=GetDate()-1 

select case when ((datepart(D,@EndDate-1)-1)/7+1) not in (2) and (datename(dw,@EndDate-1))='Saturday' then @EndDate-1 
			when ((datepart(D,@EndDate-1)-1)/7+1) in (2) and (datename(dw,@EndDate-1))='Saturday' then @EndDate-2 Else @EndDate End StartD,@EndDate EndD


CHill60

Ну и дела, спасибо.
Зачем использовать in вместо =?
Что делать, если это используется в Германии и имя даты возвращается как "Samstag"?

Edit - я только что попробовал ваш код. Это не работает, или вы изменили свои требования

kirthiga S

Я пытался в течение нескольких недель

Рейтинг:
2

CHill60

Я создал следующие тестовые данные, чтобы продемонстрировать, что вам нужно сделать - это просто ряд дат с числом для представления некоторых данных

create table #test
(
	datadate date,
	data int
)
declare @startdate date = '2018-05-01'
declare @enddate date = getdate()


;WITH q AS
    (
    SELECT  @startdate AS d1, 1 as d2
    UNION ALL
    SELECT  dateadd(d, 1, d1) , d2 + 1 
    FROM    q
    WHERE dateadd(d, 1, d1) < @enddate
    )
INSERT INTO #test
SELECT  d1, d2
FROM    q
Получить "вчерашние" данные несложно:
SELECT * FROM #test
WHERE datadate = DATEADD(d, -1, cast(getdate() as date))
То CAST это просто чтобы избавиться от элемента времени getdate() в противном случае данные не возвращаются.

Чтобы получить номер недели я использую встроенный DATEPART функция с параметром week. Е. Г.
select * FROM #test
WHERE (DATEPART(week,datadate)- DATEPART(week,DATEADD(m, DATEDIFF(m, 0, datadate), 0))) + 1 = 3


Чтобы определить, какой сегодня день недели, я не буду использовать слово "понедельник" и т. д., Поскольку это зависит от языка. Я собираюсь использовать индекс или номер дня в течение недели. Но это зависит от вашей установки @@DATEFIRSTЛюке Ат эта должность[^] обеспечивает хорошее решение:
select *, DATENAME(dw, datadate), DATEPART(dw, datadate) FROM #test 
WHERE ((DATEPART(dw, datadate) + @@DATEFIRST) % 7) NOT IN (0, 1)
Теперь вам нужно собрать все это вместе. Вы могли бы использовать CASE в WHERE да, но я не фанатка. В приведенном ниже примере я использую CTE (Common Table Expression), чтобы сначала определить, сколько дней назад я хочу включить, а затем использовать BETWEEN в простом виде WHERE пункт. Вы должны заменить его getdate() для @testdate в приведенном ниже коде:
declare @testdate date = '2018-06-12' -- '2018-05-7' -- Monday -- monday of 3rd week '2018-06-11' -- tuesday '2018-06-12'
;with q1 as 
(
	select datadate, data
	,daysback = CASE WHEN ((DATEPART(dw, @testdate) + @@DATEFIRST) % 7) = 2 AND (DATEPART(week,@testdate)- DATEPART(week,DATEADD(m, DATEDIFF(m, 0, @testdate), 0))) + 1 = 3 THEN
		-- Monday of 3rd week  so we want Fri, Sat, Sun ... this date minus 3 days
		-3
	WHEN ((DATEPART(dw, @testdate) + @@DATEFIRST) % 7) = 2  THEN
		-- any other monday so we want Sat and Sun
		-2
	ELSE
		-- any other day so just yesterday
		-1 
	END 
	from #test
)
SELECT *
from q1
WHERE datadate BETWEEN dateadd(d, daysback, @testdate) AND dateadd(d, -1, @testdate)

[Редактировать после ОП комментарий]
(Любой, кто думает, что 3 - й понедельник месяца - это то же самое, что и понедельник 3-й недели, должен рассмотреть, как вы определяете первую неделю месяца-это первая целая неделя, начинающаяся в определенный день-обычно воскресенье или понедельник, или это с 1-го по 7-е число месяца независимо от дня)

Чтобы иметь 3-й понедельник месяца, а не понедельник 3-й недели, то используйте это в CASE
WHEN ((DATEPART(dw, @testdate) + @@DATEFIRST) % 7) = 2 AND  ceiling(DAY(@testdate) / 7.0) = 3 THEN
		-3
Пояснение: Мы обсуждали это
((DATEPART(dw, @testdate) + @@DATEFIRST) % 7) = 2
найдете "понедельники". Дополнительный бит можно объяснить, разбив его на части:
DAY(@testdate)
собирается вернуть день месяца, например сегодня 18 на 18 июня 2018 года. Деление этого числа на количество дней в неделе дает вам представление о том, на какой неделе оно находится. Например, 18 / 7.0 дает 2.571428. Обратите внимание на 7.0, в противном случае 18/7 дает ответ 2. Вы можете интерпретировать это 2.571428 как "у нас уже было целых 2 понедельника в этом месяце, и теперь мы частично входим в следующий". Итак, добавив ceiling мы можем определить, что "следующий" на самом деле является 3-е место Понедельник (для этого месяца).
Ладно, это, вероятно, не самое лучшее объяснение, но, надеюсь, вы можете видеть, что происходит.

В качестве отступления (и заслуги), это было адаптировано из поста Линн Петтис, у которой есть много полезных вещей в ее блоге SQL размышления из пустыни[^] на SQL сервера.


kirthiga S

Запрос работает. Вместо понедельника 3-й недели мне нужен 3-й понедельник месяца

CHill60

Я обновил свое решение

CHill60

Связь в моем решении теперь разорвана. Замена есть Некоторые Распространенные Процедуры Даты – SQLServerCentral[^]
(Не редактируя решение, так как оно воскресит этот пост)