Holen Sie sich den Wochentag in SQL Server 2005/2008

369

Wenn ich ein Datum vom 01.01.2009 habe, möchte ich herausfinden, welcher Tag es war, z. B. Montag, Dienstag usw.

Gibt es hierfür eine integrierte Funktion in SQL Server 2005/2008? Oder muss ich einen Hilfstisch verwenden?

ein Pferd ohne Name
quelle
1
Wenn Sie eine Tabelle mit Suchvorgängen für Datumsabschnitte haben, haben Sie im Allgemeinen etwas falsch gemacht. Die Datumsfunktionen von SQL Server sind vielfältig und robust, sodass alle Daten, die Sie aus einem Datum extrahieren müssen, problemlos in einer Datums- / Uhrzeitspalte ausgeführt werden können.
Benjamin Autin
6
Hilfstabellen sind sehr nützlich für Datumsberechnungen, es ist nicht ungewöhnlich, eine Kalender-
2
"Nützlich für Datumsberechnungen" ist höchst zweifelhaft. Die meisten Datumsberechnungen können ohne Hilfstabelle durchgeführt werden und sind auch besser. In einigen Fällen erledigt eine einfache Zahlentabelle die Aufgabe - es ist keine Tabelle mit tatsächlichen Daten erforderlich. Der einzige Grund, warum ich gesehen habe, dass eine tatsächliche Kalendertabelle benötigt wird, ist, wenn die Regeln, für welche Tage Arbeitstage sind und welche Tage nicht, sehr kompliziert sind. Was ich viel zu oft gesehen habe, sind Leute, die Datumstabellen verwenden, weil sie nicht wissen, wie sie es anders machen sollen. Dann müssen sie die Datumstabelle von Zeit zu Zeit füllen. Dumm.
ErikE
5
Ich esse meine Worte, wenn Sie mir eine Verwendung für Kalendertabellen zeigen können, die 1) nicht für komplexe Feiertags- / Arbeitstagsregeln geeignet ist, 2) mit integrierten Funktionen nicht einfach möglich ist und 3) nur dann, wenn nicht # 2, dann funktioniert eine Zahlentabelle genauso gut und erfordert nicht das Auffüllen der Tabelle mit bestimmten Daten.
ErikE
2
Data Warehouses nutzen in großem Umfang Kalendertabellen. Die vorberechneten Monate, Quartale, Jahre usw. bieten den Endbenutzern Felder, nach denen sie filtern / aggregieren können.
David Rushton

Antworten:

694

Verwenden Sie DATENAMEoder DATEPART:

SELECT DATENAME(dw,GETDATE()) -- Friday
SELECT DATEPART(dw,GETDATE()) -- 6
SQLMenace
quelle
thx, ich hatte den Dateinamen ausprobiert, aber d verwendet, gab mir eine ganze Zahl zurück. dw funktioniert wie erwartet
39
Deshalb bevorzuge ich den ausgewählten Dateinamen (Wochentag, getdate ()). Ich muss mich nicht daran erinnern, dass dw Wochentag zurückgibt ... wenn ich stattdessen "Wochentag" verwenden kann.
George Mastros
9
Jeder, der darüber nachdenkt - beachten Sie, dass der Standard-Wochenbeginn Sonntag ist . Schauen Sie sich @ Sungs Antwort an, wie Sie das sicher ändern können
JonnyRaa
2
@niico ist es, weil SQL Indizes von 1, während C wie Sprachen Index von 0 indizieren.
user824276
95

Obwohl die Antwort von SQLMenace akzeptiert wurde, gibt es eine wichtige SETOption, die Sie kennen sollten

SET DATEFIRST

DATENAME wird korrektes Datum zurückgeben Namen aber nicht den gleichen DATEPART Wert , wenn der erste Tag der Woche geändert wurde , wie unten dargestellt.

declare @DefaultDateFirst int
set @DefaultDateFirst = @@datefirst
--; 7 First day of week is "Sunday" by default
select  [@DefaultDateFirst] = @DefaultDateFirst 

set datefirst @DefaultDateFirst
select datename(dw,getdate()) -- Saturday
select datepart(dw,getdate()) -- 7

--; Set the first day of week to * TUESDAY * 
--; (some people start their week on Tuesdays...)
set datefirst 2
select datename(dw,getdate()) -- Saturday
--; Returns 5 because Saturday is the 5th day since Tuesday.
--; Tue 1, Wed 2, Th 3, Fri 4, Sat 5
select datepart(dw,getdate()) -- 5 <-- It's not 7!
set datefirst @DefaultDateFirst
dance2die
quelle
33
Um einen konstanten Datumsteilwert zu erhalten, tun Sie dies ( @@datefirst - 1 + datepart(weekday, thedate) ) % 7. Der Sonntag wird immer Null sein.
Endy Tjahjono
1
irgendwie schrecklich, dass dieses Zeug statisch ist, also müssen Sie dem Original der Abfrage folgen, den Wert ändern, die Abfrage ausführen, das ursprüngliche Muster zurücksetzen
JonnyRaa
2
Ein lustiger Teil davon ist, dass die DayOfWeekAufzählung von .NET DayOfWeek.Sundayeinen Wert von .... hat 0. Unabhängig davon, worauf festgelegt DateFirstist, ist ein unbehandelter SQL-zurückgegebener WEEKDAYWert niemals mit dem .NET-Gegenstück kompatibel. Ja, Microsoft.
Eric Wu
26
SELECT  CASE DATEPART(WEEKDAY,GETDATE())  
    WHEN 1 THEN 'SUNDAY' 
    WHEN 2 THEN 'MONDAY' 
    WHEN 3 THEN 'TUESDAY' 
    WHEN 4 THEN 'WEDNESDAY' 
    WHEN 5 THEN 'THURSDAY' 
    WHEN 6 THEN 'FRIDAY' 
    WHEN 7 THEN 'SATURDAY' 
END
Sutirth
quelle
26
Sie sollten wissen, dass es eine eingebaute Funktion gibt, um dasselbe zu erreichen. select datename(dw,getdate())
Soham Dasgupta
10
@SohamDasgupta Diese integrierte Funktion gibt nicht das gleiche Ergebnis für eine nicht englische Version von MS SQL zurück.
Herr Scapegrace
12

Um einen deterministischen Wert für den Wochentag für ein bestimmtes Datum zu erhalten, können Sie eine Kombination aus DATEPART () und @@ datefirst verwenden . Ansonsten sind Sie abhängig von den Einstellungen auf dem Server.

Auf der folgenden Website finden Sie eine bessere Lösung: MS SQL: Wochentag

Der Wochentag liegt dann im Bereich von 0 bis 6, wobei 0 Sonntag, 1 Montag usw. ist. Anschließend können Sie mithilfe einer einfachen case-Anweisung den richtigen Wochentagsnamen zurückgeben.

lazerwire.com
quelle
5
Bitte geben Sie die Antwort in die Antwort ein, damit die Benutzer nicht auf einen Link klicken müssen, um dorthin zu gelangen.
Martin Smith
11

EUROPA:

declare @d datetime;
set @d=getdate();
set @dow=((datepart(dw,@d) + @@DATEFIRST-2) % 7+1);
npg
quelle
2
Bitte erläutern Sie, was Ihr Code tut und wie er die Frage beantwortet. Wenn Sie als Antwort ein Code-Snippet erhalten, wissen Sie möglicherweise nicht, was Sie damit tun sollen. Die Antwort sollte dem OP und zukünftigen Besuchern Anleitungen zum Debuggen und Beheben ihres Problems geben. Wenn Sie darauf hinweisen, welche Idee hinter Ihrem Code steckt, können Sie das Problem besser verstehen und Ihre Lösung anwenden oder ändern.
Palec
6

Ab SQL Server 2012 können Sie die FORMATFunktion verwenden

SELECT FORMAT(GETDATE(), 'dddd')
Chris Stillwell
quelle
3

Dies ist eine Arbeitskopie meines Codes. Überprüfen Sie, wie Sie den Tagesnamen vom Datum in SQL abrufen können

CREATE Procedure [dbo].[proc_GetProjectDeploymentTimeSheetData] 
@FromDate date,
@ToDate date

As 
Begin
select p.ProjectName + ' ( ' + st.Time +' '+'-'+' '+et.Time +' )' as ProjectDeatils,
datename(dw,pts.StartDate) as 'Day'
from 
ProjectTimeSheet pts 
join Projects p on pts.ProjectID=p.ID 
join Timing st on pts.StartTimingId=st.Id
join Timing et on pts.EndTimingId=et.Id
where pts.StartDate >= @FromDate
and pts.StartDate <= @ToDate
END
Tapan Kumar
quelle
1

Wenn Sie nicht abhängig sein @@DATEFIRSToder verwenden möchten DATEPART(weekday, DateColumn), berechnen Sie einfach den Wochentag selbst.

Für montagsbasierte Wochen (Europa) ist am einfachsten:

SELECT DATEDIFF(day, '17530101', DateColumn) % 7 + 1 AS MondayBasedDay

Für Sonntagswochen (Amerika) verwenden Sie:

SELECT DATEDIFF(day, '17530107', DateColumn) % 7 + 1 AS SundayBasedDay

Dies gibt die Wochentagsnummer (1 bis 7) seit dem 1. Januar bzw. dem 7. Januar 1753 zurück.

Michel de Ruiter
quelle
1

Sie können verwenden, DATEPART(dw, GETDATE())aber beachten Sie, dass das Ergebnis vom SQL Server-Einstellungswert @@DATEFIRSTabhängt, der der erste Wochentag ist (in Europa ist der Standardwert 7 der Sonntag).

Wenn Sie den ersten Wochentag in einen anderen Wert ändern möchten, können Sie ihn verwenden. SET DATEFIRSTDies kann sich jedoch auf alle Bereiche Ihrer Abfragesitzung auswirken, die Sie nicht möchten.

Alternativ können Sie den Wert für den ersten Wochentag explizit als Parameter angeben und je nach @@DATEFIRSTEinstellung vermeiden . Sie können die folgende Formel verwenden, um dies bei Bedarf zu erreichen:

(DATEPART(dw, GETDATE()) + @@DATEFIRST + 6 - @WeekStartDay) % 7 + 1

Wo @WeekStartDayist der erste Wochentag, den Sie für Ihr System wünschen (von 1 bis 7, dh von Montag bis Sonntag)?

Ich habe es in die folgende Funktion eingewickelt, damit wir es leicht wiederverwenden können:

CREATE FUNCTION [dbo].[GetDayInWeek](@InputDateTime DATETIME, @WeekStartDay INT)
RETURNS INT
AS
BEGIN
    --Note: @WeekStartDay is number from [1 - 7] which is from Monday to Sunday
    RETURN (DATEPART(dw, @InputDateTime) + @@DATEFIRST + 6 - @WeekStartDay) % 7 + 1 
END

Anwendungsbeispiel: GetDayInWeek('2019-02-04 00:00:00', 1)

Dies entspricht den folgenden Einstellungen (unabhängig von der Einstellung DATEFIRST des SQL-Servers):

SET DATEFIRST 1
DATEPART(dw, '2019-02-04 00:00:00')
Minh Nguyen
quelle
0

Sie können diese Version nützlich finden.

-- Test DATA
select @@datefirst
create table #test (datum datetime)
insert #test values ('2013-01-01')
insert #test values ('2013-01-02')
insert #test values ('2013-01-03')
insert #test values ('2013-01-04')
insert #test values ('2013-01-05')
insert #test values ('2013-01-06')
insert #test values ('2013-01-07')
insert #test values ('2013-01-08')
-- Test DATA

select  Substring('Sun,Mon,Tue,Wed,Thu,Fri,Sat,Sun,Mon,Tue,Wed,Thu,Fri,Sat',
        (DATEPART(WEEKDAY,datum)+@@datefirst-1)*4+1,3),Datum
        from #test 
Reto
quelle
1
Dies ist stumpfer Code und gibt keinen Hinweis darauf, was er tut oder zu erreichen versucht
Brewmanz