Ayuda para consultas SQL:Transformar fechas de una manera no trivial
-
01-07-2019 - |
Pregunta
Tengo una tabla con una columna "Fecha" y me gustaría hacer una consulta que haga lo siguiente:
Si la fecha es un Lunes, Martes, Miércoles, o Jueves, la fecha mostrada debe adelantarse 1 día, como en
DATEADD(day, 1, [Date])Por otro lado, si se trata de un Viernes, la fecha mostrada debe incrementarse en 3 días (es decir,entonces queda lo siguiente Lunes).
¿Cómo hago esto en mi declaración SELECT?Como en,
SELECT somewayofdoingthis([Date]) FROM myTable
(Este es SQL Server 2000.)
Solución
Así es como lo haría.Recomiendo una función como la anterior si la usará en otros 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]
Otros consejos
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
Intentar
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]
Supongo que también desea que el sábado y el domingo pasen al lunes siguiente.Si ese no es el caso, saque el 1 de (1,2,3,4,5) y elimine la última cláusula cuando.
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
También puedes hacerlo en una línea:
select dateadd(day, 1 + (datepart(weekday, [Date])/6) * (8-datepart(weekday, [Date])), [Date])
Suena como una expresión CASE.No conozco las manipulaciones de datos adecuadas para SQL Server, pero básicamente se vería así:
CASE
WHEN [Date] is a Friday THEN DATEADD( day, 3, [Date] )
ELSE DATEADD( day, 1, [Date] )
END
Si desea verificar los días de fin de semana, puede agregar cláusulas WHEN adicionales antes de ELSE.
podrías usar esto:
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
Busque la declaración CASE y la declaración DATEPART.Querrá utilizar el argumento dw con DATEPART para recuperar un número entero que represente el día de la semana.
Esto está fuera de mi cabeza y se puede limpiar claramente, pero utilícelo como punto 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
...
¿Qué tal si tomamos una página del Almacén de datos chicos y hagan una mesa.En términos de DW, esta sería una dimensión de fecha.A dimensión de fecha estándar tendría cosas como varios nombres para una fecha ("MON", "lunes", "22 de agosto de 1998") o indicadores como fin de mes y comienzo de mes.Sin embargo, también puede tener columnas que sólo tengan sentido en su entorno.
Por ejemplo, según la pregunta, la suya podría tener una columna del siguiente día laborable que apuntaría a la clave del día en cuestión.De esa manera, puede personalizarlo aún más para tener en cuenta los días festivos u otros días no laborables.
La gente de DW es inflexible en cuanto al uso de claves sin sentido (es decir, no utilice simplemente una fecha truncada como clave, utilice una clave generada), pero usted puede decidirlo usted mismo.
El Kit de herramientas de dimensión de fecha tiene código para generar sus propias tablas en varios DBMS y tiene datos CSV para fechas de varios años.
necesita crear una función SQL que realice esta transformación por usted.
Esto es principalmente como el de Brian, excepto que no se compiló debido a pares no coincidentes y cambié el IF para que no tuviera la selección.Es importante tener en cuenta que aquí utilizamos DateNAME en lugar de datePART porque datePART depende del valor establecido por SET DATEFIRST, que establece el primer día de la 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