Справка по SQL-запросу: нетривиальное преобразование дат

У меня есть таблица со столбцом «Дата», и я хотел бы выполнить запрос, который выполняет следующие действия:

Если дата - понедельник, вторник, среда или Четверг, отображаемая дата должна быть сдвинута на 1 день вверх, как в

DATEADD(day, 1, [Date])
On the other hand, if it is a Пятница, the displayed date should be incremented by 3 days (i.e. so it becomes the following понедельник).

Как мне сделать это в моем операторе SELECT? Как в,

SELECT somewayofdoingthis([Date]) FROM myTable

(Это SQL Server 2000.)

Что должно произойти в субботу и воскресенье?

Brian 20.09.2008 00:59
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
3
1
1 828
12
Перейти к ответу Данный вопрос помечен как решенный

Ответы 12

вам необходимо создать функцию SQL, которая выполняет это преобразование за вас.

Похоже на выражение CASE. Я не знаю, как правильно обрабатывать данные для SQL Server, но в основном это будет выглядеть так:

CASE
  WHEN [Date] is a Friday THEN DATEADD( day, 3, [Date] )
  ELSE DATEADD( day, 1, [Date] )
END

Если вы хотите проверить выходные дни, вы можете добавить дополнительные предложения WHEN перед ELSE.

Это не в моей голове, и его можно очистить, но используйте его как отправную точку:

select case when DATENAME(dw, [date]) = 'Monday' then DATEADD(dw, 1, [Date])
                when DATENAME(dw, [date]) = 'Tuesday' then DATEADD(dw, 1, [Date])
                when DATENAME(dw, [date]) = 'Wednesday' then DATEADD(dw, 1, [Date])
                when DATENAME(dw, [date]) = 'Thursday' then DATEADD(dw, 1, [Date])
                when  DATENAME(dw, [date]) = 'Friday' then DATEADD(dw, 3, [Date])
          end as nextDay
    ...

вы можете использовать это:

select dayname,newdayname =
    CASE dayname
    WHEN 'Monday' THEN 'Tuesday'
    WHEN 'Tuesday' THEN 'Wednesday'
    WHEN 'Wednesday' THEN 'Thursday'
    WHEN 'Thursday' THEN 'Friday'
    WHEN 'Friday' THEN 'Monday'
    WHEN 'Saturday' THEN 'Monday'
    WHEN 'Sunday' THEN 'Monday'
END
FROM UDO_DAYS
results:
Monday       Tuesday
Tuesday      Wednesday
Wednesday    Thursday
Thursday     Friday
Friday       Monday
Saturday     Monday
Sunday       Monday

table data:
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
Ответ принят как подходящий

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

CASE
WHEN
    DATEPART(dw, [Date]) IN (2,3,4,5)
THEN
    DATEADD(d, 1, [Date])
WHEN
    DATEPART(dw, [Date]) = 6
THEN
    DATEADD(d, 3, [Date])
ELSE
    [Date]
END AS [ConvertedDate]

из справки sql, поэтому может работать не для всех настроек: datepart для дня недели (dw) возвращает число, соответствующее дню недели, например: воскресенье = 1, суббота = 7. Число, полученное с помощью datepart для дня недели, зависит от значение, установленное SET DATEFIRST. Это устанавливает первый день недели.

Adriaan Stander 16.07.2009 16:55

CREATE FUNCTION dbo.GetNextWDay(@Day datetime)
RETURNS DATETIME
AS
BEGIN 
    DECLARE @ReturnDate DateTime

    set @ReturnDate = dateadd(dd, 1, @Day)

    if (select datename(@ReturnDate))) = 'Saturday'
        set @ReturnDate = dateadd(dd, 2, @ReturnDate)

    if (select datename(@ReturnDate) = 'Sunday'
        set @ReturnDate = dateadd(dd, 1, @ReturnDate)

    RETURN @ReturnDate
END

Найдите оператор CASE и оператор DATEPART. Вы можете использовать аргумент dw с DATEPART, чтобы получить целое число, представляющее день недели.

Пытаться

select case  when datepart(dw,[Date]) between 2 and 5 then DATEADD(dd, 1, [Date])
when datepart(dw,[Date]) = 6 then DATEADD(dd, 3, [Date]) else [Date] end as [Date] 

create table #dates (dt datetime)
insert into #dates (dt) values ('1/1/2001')
insert into #dates (dt) values ('1/2/2001')
insert into #dates (dt) values ('1/3/2001')
insert into #dates (dt) values ('1/4/2001')
insert into #dates (dt) values ('1/5/2001')

    select
        dt, day(dt), dateadd(dd,1,dt)
    from
        #dates
    where
        day(dt) between 1 and 4

    union all

    select
        dt, day(dt), dateadd(dd,3,dt)
    from
        #dates
    where
        day(dt) = 5

    drop table #dates

Я предполагаю, что вы также хотите перенести субботу и воскресенье на следующий понедельник. Если это не так, возьмите 1 из (1,2,3,4,5) и удалите последнее предложение when.

case
   --Sunday thru Thursday are shifted forward 1 day
   when datepart(weekday, [Date]) in (1,2,3,4,5) then dateadd(day, 1, [Date]) 
   --Friday is shifted forward to Monday
   when datepart(weekday, [Date]) = 6  then dateadd(day, 3, [Date])
   --Saturday is shifted forward to Monday
   when datepart(weekday, [Date]) = 7  then dateadd(day, 2, [Date])
end

Вы также можете сделать это одной строкой:

select dateadd(day, 1 + (datepart(weekday, [Date])/6) * (8-datepart(weekday, [Date])), [Date])

Это в основном похоже на Брайана, за исключением того, что он не компилировался из-за несоответствия скобок, и я изменил IF, чтобы в нем не было выбора. Важно отметить, что мы используем здесь DateNAME, а не datePART, потому что datePART зависит от значения, установленного SET DATEFIRST, которое устанавливает первый день недели.

CREATE FUNCTION dbo.GetNextWDay(@Day datetime)
RETURNS DATETIME
AS
BEGIN
    DECLARE @ReturnDate DateTime

    set @ReturnDate = dateadd(dd, 1, @Day)
    if datename(dw, @ReturnDate) = 'Saturday'
        set @ReturnDate = dateadd(dd, 2, @ReturnDate)
    if datename(dw, @ReturnDate) = 'Sunday'
        set @ReturnDate = dateadd(dd, 1, @ReturnDate)
    RETURN @ReturnDate
END

Как насчет того, чтобы взять страницу у ребят из Хранилище данных и сделать таблицу. В терминах DW это будет измерение даты. стандартное измерение даты может иметь различные названия для даты («МЕСЯЦ», «Понедельник», «22 августа 1998 г.») или индикаторы, такие как конец месяца и начало месяца. Однако у вас также могут быть столбцы, которые имеют смысл только в вашей среде.

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

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

Набор инструментов для измерения даты имеет код для создания ваших собственных таблиц в различных СУБД и содержит данные CSV за несколько лет.

Другие вопросы по теме