Pergunta

Eu tenho uma tabela com uma coluna "Data", e eu gostaria de fazer uma consulta que faz o seguinte:

Se a data é um Segunda-feira , Terça-feira , Quarta-feira ou Quinta-feira , a data exibida deve ser deslocou-se por um dia, como em

DATEADD(day, 1, [Date])
por outro lado, se é um Sexta-feira , a data exibida deve ser incrementado por 3 dias (ou seja, para que se torne o seguinte segunda-feira ).

Como posso fazer isso no meu instrução SELECT? Como em,

SELECT somewayofdoingthis([Date]) FROM myTable

(Este é o SQL Server 2000).

Foi útil?

Solução

Aqui está como eu faria isso. Eu recomendo uma função como acima se você vai usar isso em outros lugares.

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]

Outras dicas

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

Tente

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] 

Estou assumindo que você também quer sábado e domingo para deslocar para a frente para a segunda-feira seguinte. Se isso não for o caso, tomar a 1 de (1,2,3,4,5) e remover o último quando cláusula.

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

Você também pode fazê-lo em uma linha:

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

soa como uma expressão CASE. Eu não sei as manipulações de dados adequadas para SQL Server, mas basicamente ficaria assim:

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

Se você quiser verificar se há dias de fim de semana você pode adicionar adicional quando as cláusulas antes da outra pessoa.

Você pode utilizar isto:

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

Procure a instrução CASE ea declaração DATEPART. Você vai querer usar o argumento dw com DATEPART para voltar um inteiro que representa o dia da semana.

Este é fora do topo da minha cabeça e pode ser claramente limpo, mas usá-lo como ponto de partida:

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
    ...

Que tal tomar uma página do caras Data Warehouse e fazer uma tabela. Em termos DW, esta seria uma dimensão de data. A dimensão de data padrão teria coisas como vários nomes para uma data ( "MON", "Monday" "22 de agosto de 1998"), ou indicadores como fim-de-mês e de início de mês. No entanto, você também pode ter colunas que só fazem sentido no seu ambiente.

Por exemplo, com base na pergunta, a sua pode ter uma coluna próxima-dia de trabalho que apontam para a chave para o dia em questão. Dessa forma, você pode personalizá-lo ainda mais para tomar em consideração os feriados ou outros dias não úteis.

O pessoal DW são inflexíveis sobre como utilizar teclas sem sentido (ou seja, não basta usar uma data truncado como a chave, use uma chave gerada), mas você pode decidir isso por si mesmo.

O Data Dimension Toolkit tem código para gerar suas próprias tabelas em vários DBMS e tem CSV dados para vários anos no valor de datas.

você precisa criar uma função SQL que faz essa transformação para você.

Isto é principalmente como Brian de exceto que ele não compilar devido a parens incompatíveis e eu mudei o IF para não ter a escolha nele. É importante notar que usamos DATENAME aqui em vez de datepart porque datepart é dependente do valor definido pelo SET DATEFIRST, que define o primeiro dia da semana.

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
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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top