SQL Server 2005/2008'de haftanın gününü alın


369

01/01/2009 tarihim varsa, günün hangi gün olduğunu öğrenmek istiyorum, örneğin Pazartesi, Salı, vb ...

SQL Server 2005/2008'de bunun için yerleşik bir işlev var mı? Veya yardımcı bir tablo kullanmam gerekir mi?


1
Tarih bölümleri için aramaları içeren bir tablonuz varsa, genellikle yanlış bir şey yaptınız. SQL Server'ın tarih işlevleri çok ve sağlamdır, bu nedenle bir tarihten ayıklamanız gereken tüm veriler bir tarih / saat sütununda kolayca yapılabilir.
Benjamin Autin

6
yardımcı tablolar tarih hesaplamaları için çok yararlıdır, bir takvim yardımcı tabloya sahip olmak olağandışı değildir ...

2
"Tarih hesaplamaları için kullanışlıdır" oldukça şüphelidir. Tarih hesaplamalarının çoğu herhangi bir yardımcı tablo olmadan yapılabilir ve daha iyi performans gösterir. Bazı durumlarda, düz bir Sayılar tablosu işi yapar - içinde gerçek tarihleri ​​olan bir tabloya gerek yoktur. Gerçek bir takvim tablosunun gerekli olduğunu görmemin tek nedeni, hangi günlerin iş günü olduğu ve hangi günlerin çok karmaşık olmadığıdır. Ne sık sık gördüm ne tarih tabloları kullanan insanlar çünkü onlar başka bir şekilde nasıl yapılacağını bilmiyorum. Sonra tarih tablosunu sık sık doldurmaları gerekir. Aptal.
ErikE

5
Bana 1) karmaşık tatil / iş günü kuralları için değil, 2) yerleşik işlevlerle kolayca yapılamayacağını ve 3) sadece # değilse 2 ise, bir Sayılar tablosu da aynı şekilde çalışır ve tablonun belirli tarihlerle doldurulmasını gerektirmez.
ErikE

2
Veri ambarları, takvim tablolarını kapsamlı bir şekilde kullanır. Önceden hesaplanan aylar, çeyrekler, yıllar vb., Son kullanıcılara karşı filtre uygulayabilecekleri / toplayabilecekleri alanlar sağlar.
David Rushton

Yanıtlar:


694

DATENAMEVeya kullanın DATEPART:

SELECT DATENAME(dw,GETDATE()) -- Friday
SELECT DATEPART(dw,GETDATE()) -- 6

thx, datename denedim ama d kullandım, bana bir tamsayı verdi. dw beklendiği gibi çalışıyor

39
Bu yüzden select datename (hafta içi, getdate ()) kullanmayı tercih ediyorum. Ben dw hafta içi döner hatırlıyorum zorunda değil .... yerine "hafta içi" kullanabilirsiniz.
George Mastros

9
Herkes buna göz gezdiriyor - haftanın varsayılan başlangıcının pazar olduğunu unutmayın . Bunu güvenli bir şekilde nasıl değiştirebileceğine @
Sung'un cevabına bak

2
@niico bunun nedeni SQL'in 1'den indekslenmesi, C'nin dilin 0'dan indekslenmesi.
user824276

95

SQLMenace'in yanıtı kabul edilmiş olsa da, SETbilmeniz gereken önemli bir seçenek var

DATEFIRST AYARLA

DATENAME doğru tarih adını döndürür, ancak haftanın ilk günü aşağıda gösterildiği gibi değiştirilirse aynı DATEPART değerini döndürmez .

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

33
Böylece sabit bir datepart değeri elde edersiniz ( @@datefirst - 1 + datepart(weekday, thedate) ) % 7. Pazar her zaman sıfır olacaktır.
Endy Tjahjono

1
kindof horrible Bu şeyler statik yani orijinal sorguyu takip et, değeri değiştir, sorguyu çalıştır, orijinal kalıbı sıfırla
JonnyRaa

2
Bunun komik kısmı .NET'in DayOfWeeknumaralandırmasının DayOfWeek.Sunday... değerine sahip olmasıdır 0. Bu nedenle, ne DateFirstayarlanırsa yapılsın, işlenmemiş bir SQL döndürülen WEEKDAYdeğer asla .NET karşılığıyla uyumlu olmayacaktır. Yay, 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

26
Bunu başarmak için yerleşik bir fonksiyon olduğunu bilmelisiniz. select datename(dw,getdate())
Soham Dasgupta

10
@SohamDasgupta bu yerleşik işlev MS SQL ingilizce olmayan sürümü için aynı sonucu döndürmez.
Bay Scapegrace

12

Belirli bir tarih için haftanın günü için deterministik bir değer elde etmek için DATEPART () ve @@ datefirst kombinasyonunu kullanabilirsiniz . Aksi takdirde sunucudaki ayarlara bağımlı olursunuz.

Daha iyi bir çözüm için aşağıdaki siteye göz atın: MS SQL: Haftanın Günü

Daha sonra haftanın günü 0 ila 6 aralığında olacaktır, burada 0 Pazar, 1 Pazartesi'dir, vb. Daha sonra doğru hafta içi adını döndürmek için basit bir vaka ifadesi kullanabilirsiniz.


5
Lütfen cevabı cevaba koyun, böylece insanların cevabı almak için bir bağlantıyı tıklaması gerekmez.
Martin Smith

11

AVRUPA:

declare @d datetime;
set @d=getdate();
set @dow=((datepart(dw,@d) + @@DATEFIRST-2) % 7+1);

2
Lütfen kodunuzun ne yaptığını ve soruyu nasıl yanıtladığını açıklayınız. Yanıt olarak bir kod snippet'i alırsanız, bununla ne yapacağınızı bilemeyebilirsiniz. Cevap, OP ve gelecekteki ziyaretçilere sorunlarının nasıl hata ayıklanacağı ve düzeltileceği konusunda rehberlik etmelidir. Kodunuzun arkasındaki fikrin ne olduğunu belirtmek, sorunu anlamanıza ve çözümünüzü uygulamaya veya değiştirmeye büyük ölçüde yardımcı olur.
Palec

6

SQL Server 2012 ile ve ileriye kullanabilirsiniz FORMATişlevi

SELECT FORMAT(GETDATE(), 'dddd')

3

Bu benim kod çalışma kopyasını kontrol edin, sql gün tarihinden nasıl yeniden

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

1

Güvenmek @@DATEFIRSTveya kullanmak istemiyorsanız DATEPART(weekday, DateColumn), haftanın gününü kendiniz hesaplayın.

Pazartesi günleri (Avrupa) için en basit olanı:

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

Pazar günleri (Amerika) için şunları kullanın:

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

Bu, 1 Ocak'tan bu yana hafta içi sayıyı (1-7) sırasıyla 7, 1753'te verir.


1

DATEPART(dw, GETDATE())Sonucun @@DATEFIRSThaftanın ilk günü ayarı olan SQL Server ayar değerine bağlı olacağını da kullanabilirsiniz (Avrupa'da, Pazar olan varsayılan değer 7'dir).

Haftanın ilk gününü başka bir değere değiştirmek istiyorsanız, SET DATEFIRST ancak bu, sorgu oturumunuzda istemediğiniz her yeri etkileyebilir.

Alternatif yol, haftanın ilk gün değerini parametre olarak açıkça belirtmek ve @@DATEFIRSTayara bağlı olarak kaçınmaktır . İhtiyaç duyduğunuzda bunu elde etmek için aşağıdaki formülü kullanabilirsiniz:

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

@WeekStartDaysisteminiz için haftanın ilk günü nerede (1'den 7'ye, yani Pazartesi'den Pazar'a).

Kolayca tekrar kullanabilmemiz için aşağıdaki fonksiyona sardım:

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

Örnek kullanım: GetDayInWeek('2019-02-04 00:00:00', 1)

Aşağıdakine eşdeğerdir (ancak SQL Server DATEFIRST ayarından bağımsızdır):

SET DATEFIRST 1
DATEPART(dw, '2019-02-04 00:00:00')

0

Bu sürümü faydalı bulabilirsiniz.

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

1
Bu geniş bir koddur ve ne yaptığını veya elde etmeye çalıştığını gösteren hiçbir belirti
vermez
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.