SQL Query Help: Transforming Daten in einem nicht-triviale Weise
-
01-07-2019 - |
Frage
Ich habe eine Tabelle mit einer Spalte „Datum“, und ich möchte eine Abfrage tun, macht folgendes:
Wenn das Datum ist ein Montag , Dienstag , Mittwoch oder Donnerstag , sollte das angezeigte Datum sein verschoben um 1 Tag auf, wie in
DATEADD(day, 1, [Date])auf der anderen Seite, wenn es um 3 Tage in der Freitag , das angezeigte Datum erhöht werden (dh so wird es die folgende ist, sollte montag ).
Wie mache ich dies in meiner SELECT-Anweisung? Wie in,
SELECT somewayofdoingthis([Date]) FROM myTable
(Dies ist SQL Server 2000).
Lösung
Hier ist, wie ich es tun würde. Ich habe eine Funktion wie oben empfehlen, wenn Sie an anderen Orten mit diesem wird.
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]
Andere Tipps
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
Versuchen
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]
Ich gehe davon aus, dass Sie auch Samstag und Sonntag wollen sich auf den folgenden Montag zu verschieben. Ist dies nicht der Fall ist, nehmen Sie die 1 aus (1,2,3,4,5) und entfernen Sie die letzte, wenn Klausel.
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
Sie können auch tun es in einer Zeile:
select dateadd(day, 1 + (datepart(weekday, [Date])/6) * (8-datepart(weekday, [Date])), [Date])
Klingt wie ein CASE-Ausdruck. Ich weiß nicht, die richtigen Datenmanipulationen für SQL Server, aber im Grunde würde es so aussehen:
CASE
WHEN [Date] is a Friday THEN DATEADD( day, 3, [Date] )
ELSE DATEADD( day, 1, [Date] )
END
Wenn Sie wollten für Wochenendtage überprüfen, können Sie weitere hinzufügen, wenn Klauseln vor dem ELSE.
Sie können diese verwenden:
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
Die CASE-Anweisung und die Anweisung DATEPART nachschlagen. Sie werden die dw Argument mit DATEPART verwenden möchten, eine ganze Zahl zu kommen, die den Tag der Woche darstellt.
Dies ist aus der Spitze von meinem Kopf und deutlich gereinigt werden kann, aber es als Ausgangspunkt verwendet werden:
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
...
Wie wäre es, eine Seite aus den Data Warehouse Jungs nehmen und einen Tisch machen. In DW Bedingungen wäre dies ein Datum Dimension sein. Eine Standard Datumsdimension würde für ein Datum Dinge wie verschiedene Namen hat ( „MON“, „Montag“ "22. August 1998") oder Indikatoren wie End-of-Monats-und Start-of-Monat. Sie können jedoch auch Spalten, die nur Sinn in Ihrer Umgebung zu machen.
Zum Beispiel auf der Grundlage der Frage, könnten Sie eine Next-Work-Tag-Spalte, die auf den Schlüssel für den betreffenden Tag zeigen würden. Auf diese Weise können sie weiter anpassen können berücksichtigt Urlaub nehmen oder andere Nicht-Arbeitstage.
Die DW Leute sind unnachgiebig mit sinnlosen Schlüssel (das heißt, nicht einfach ein verkürztes Datum als Schlüssel verwenden, verwenden Sie einen generierten Schlüssel), aber Sie können das für sich selbst entscheiden.
Die Datum Dimension Toolkit Code hat Ihre eigenen Tabellen in verschiedenen DBMS zu erzeugen, und es hat CSV Daten für mehrere Jahre im wert von Terminen.
Sie müssen eine SQL-Funktion erstellen, die diese Transformation für Sie tun.
ist meist wie Brians außer es nicht aufgrund nicht übereinstimmen Pars kompilieren und änderte ich die IF nicht die Auswahl in ihm. Es ist wichtig zu beachten, dass wir hier datename statt Datumsteil verwenden, da Datepart auf dem Wert von SET DATEFIRST abhängig ist, die den ersten Tag der Woche setzt.
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