SQL Query Help: Trasformare le date in modo non banale
-
01-07-2019 - |
Domanda
Ho una tabella con una " Data " colonna e vorrei fare una query che procede come segue:
Se la data è un lunedì , martedì , mercoledì o giovedì , la data visualizzata dovrebbe essere spostato di 1 giorno, come in
DATEADD(day, 1, [Date])D'altra parte, se è un venerdì , la data visualizzata dovrebbe essere incrementata di 3 giorni (ovvero diventa la seguente < em> Lunedi ).
Come posso farlo nella mia istruzione SELECT? Come in
SELECT somewayofdoingthis([Date]) FROM myTable
(Questo è SQL Server 2000.)
Soluzione
Ecco come lo farei. Consiglio una funzione come sopra se la userete in altri luoghi.
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]
Altri suggerimenti
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
Prova
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]
Suppongo che tu voglia anche sabato e domenica per passare al lunedì successivo. In caso contrario, prendi 1 su (1,2,3,4,5) e rimuovi l'ultima clausola 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
Puoi anche farlo in una riga:
select dateadd(day, 1 + (datepart(weekday, [Date])/6) * (8-datepart(weekday, [Date])), [Date])
Sembra un'espressione CASE. Non conosco le manipolazioni dei dati corrette per SQL Server, ma sostanzialmente sarebbe simile a questo:
CASE
WHEN [Date] is a Friday THEN DATEADD( day, 3, [Date] )
ELSE DATEADD( day, 1, [Date] )
END
Se si desidera verificare i giorni del fine settimana, è possibile aggiungere ulteriori clausole QUANDO prima dell'ELSE.
puoi usare questo:
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
Cerca l'istruzione CASE e l'istruzione DATEPART. Dovrai utilizzare l'argomento dw con DATEPART per recuperare un numero intero che rappresenta il giorno della settimana.
Questo è dalla parte superiore della mia testa e può essere chiaramente ripulito ma usarlo come punto di partenza:
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
...
Che ne dici di prendere una pagina dai Data Warehouse e fare un tavolo. In termini di DW, questa sarebbe una dimensione data. Una dimensione data standard avrebbe cose come vari nomi per una data (" MON " ;, " Lunedì "," 22 agosto 1998 ", o indicatori come fine del mese e inizio del mese. Tuttavia, puoi anche avere colonne che hanno senso solo nel tuo ambiente.
Ad esempio, in base alla domanda, la tua potrebbe avere una colonna del giorno lavorativo successivo che indichi la chiave per il giorno in questione. In questo modo è possibile personalizzarlo ulteriormente per tenere conto delle festività o di altri giorni non lavorativi.
Le persone DW sono irremovibili nell'usare chiavi insignificanti (cioè, non usare solo una data troncata come chiave, usare una chiave generata), ma puoi decidere tu stesso.
Il Date Dimension Toolkit ha un codice per generare le tue tabelle in vari DBMS e ha CSV dati per diversi anni di date.
devi creare una funzione SQL che esegua questa trasformazione per te.
Questo è per lo più come quello di Brian, tranne per il fatto che non è stato compilato a causa di parentesi non corrispondenti e ho cambiato l'IF per non avere la selezione in esso. È importante notare che qui usiamo DateNAME anziché datePART perché datePART dipende dal valore impostato da SET DATEFIRST, che imposta il primo giorno della settimana.
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