Dapatkan hari dalam seminggu di SQL Server 2005/2008

369

Jika saya memiliki tanggal 01/01/2009, saya ingin mencari tahu hari apa itu misalnya Senin, Selasa, dll ...

Apakah ada fungsi bawaan untuk ini di SQL Server 2005/2008? Atau apakah saya perlu menggunakan tabel bantu?

seekor kuda tanpa nama
sumber
1
Jika Anda memiliki tabel yang berisi pencarian untuk bagian tanggal, Anda umumnya melakukan kesalahan. Fungsi tanggal SQL Server banyak dan kuat sehingga setiap data yang Anda butuhkan untuk mengekstrak dari tanggal dapat dengan mudah dilakukan pada kolom datetime.
Benjamin Autin
6
tabel tambahan yang sangat berguna untuk perhitungan tanggal, itu tidak biasa untuk memiliki kalender meja tambahan ...
2
"Berguna untuk perhitungan tanggal" sangat meragukan. Sebagian besar perhitungan tanggal dapat ditangani tanpa jenis tabel tambahan dan akan berkinerja lebih baik juga. Dalam beberapa kasus, tabel Angka sederhana akan melakukan pekerjaan - tidak perlu meja dengan tanggal aktual di dalamnya. Satu-satunya alasan saya telah melihat bahwa tabel kalender yang sebenarnya diperlukan adalah ketika aturan untuk hari mana yang merupakan hari kerja dan hari yang tidak terlalu rumit. Apa yang saya terlalu sering lihat adalah orang-orang menggunakan tabel tanggal karena mereka tidak tahu bagaimana melakukannya dengan cara lain. Kemudian mereka harus mengisi tabel tanggal sesering mungkin. Bodoh.
ErikE
5
Saya akan makan kata-kata saya jika Anda dapat menunjukkan kepada saya penggunaan untuk tabel kalender yang 1) bukan untuk aturan hari libur / hari kerja yang kompleks, 2) tidak dapat dengan mudah dilakukan dengan fungsi bawaan, dan 3) hanya jika tidak # 2, maka tabel Numbers berfungsi dengan baik dan tidak perlu mengisi tabel dengan tanggal tertentu.
ErikE
2
Gudang data banyak menggunakan tabel kalender. Bulan, kwartal, tahun, dll yang telah dihitung sebelumnya memberi pengguna akhir bidang yang dapat mereka filter / gabungkan.
David Rushton

Jawaban:

694

Gunakan DATENAMEatau DATEPART:

SELECT DATENAME(dw,GETDATE()) -- Friday
SELECT DATEPART(dw,GETDATE()) -- 6
SQLMenace
sumber
thx, saya sudah mencoba nama file tetapi menggunakan d, memberi saya integer kembali. dw berfungsi seperti yang diharapkan
39
Itu sebabnya saya lebih suka menggunakan pilih nama file (hari kerja, getdate ()). Saya tidak harus ingat bahwa dw mengembalikan hari kerja .... ketika saya dapat menggunakan "hari kerja" sebagai gantinya.
George Mastros
9
siapa pun melirik ini - perhatikan bahwa awal minggu standar adalah minggu . Lihatlah jawaban @ Sung untuk bagaimana mengubahnya dengan aman
JonnyRaa
2
@ Niico itu karena indeks SQL dari 1 sedangkan C seperti indeks bahasa dari 0.
user824276
95

Meskipun jawaban SQLMenace telah diterima, ada satu SETopsi penting yang harus Anda ketahui

SET DATEFIRST

DATENAME akan mengembalikan nama tanggal yang benar tetapi tidak dengan nilai DATEPART yang sama jika hari pertama dalam seminggu telah diubah sebagaimana diilustrasikan di bawah ini.

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
sumber
33
Jadi untuk mendapatkan nilai bagian data yang konstan, Anda harus melakukannya ( @@datefirst - 1 + datepart(weekday, thedate) ) % 7. Hari Minggu akan selalu nol.
Endy Tjahjono
1
kindof mengerikan hal ini statis sehingga Anda harus mengikuti kueri asli, mengubah nilai, menjalankan kueri, mengatur ulang pola asli
JonnyRaa
2
Lucu bagian dari ini adalah bahwa NET DayOfWeekpencacahan memiliki DayOfWeek.Sundaydengan nilai ... 0. Jadi, tidak peduli apa DateFirstsetted untuk, sebuah diobati SQL-kembali WEEKDAYnilai tidak akan pernah kompatibel dengan NET rekan. 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
Sutirth
sumber
26
Anda harus tahu bahwa ada fungsi bawaan untuk mencapai hal yang sama. select datename(dw,getdate())
Soham Dasgupta
10
@SohamDasgupta fungsi bawaan ini tidak mengembalikan hasil yang sama untuk MS SQL versi non-Inggris.
Tuan Scapegrace
12

Untuk mendapatkan nilai deterministik untuk hari dalam seminggu untuk tanggal tertentu, Anda dapat menggunakan kombinasi DATEPART () dan @@ datefirst . Kalau tidak, Anda tergantung pada pengaturan di server.

Lihatlah situs berikut untuk solusi yang lebih baik: MS SQL: Day of Week

Hari dalam seminggu akan berada dalam kisaran 0 hingga 6, di mana 0 adalah hari Minggu, 1 adalah hari Senin, dll. Kemudian Anda dapat menggunakan pernyataan kasus sederhana untuk mengembalikan nama hari kerja yang benar.

lazerwire.com
sumber
5
Harap masukkan jawabannya ke dalam jawaban sehingga orang tidak perlu mengklik tautan untuk mendapatkannya.
Martin Smith
11

EROPA:

declare @d datetime;
set @d=getdate();
set @dow=((datepart(dw,@d) + @@DATEFIRST-2) % 7+1);
npg
sumber
2
Harap sertakan penjelasan tentang apa yang kode Anda lakukan dan bagaimana ia menjawab pertanyaan itu. Jika Anda mendapatkan potongan kode sebagai jawaban, Anda mungkin tidak tahu apa yang harus dilakukan dengannya. Jawaban harus memberi OP dan panduan pengunjung di masa mendatang tentang cara debug dan memperbaiki masalah mereka. Menunjukkan, apa ide di balik kode Anda, sangat membantu dalam memahami masalah dan menerapkan atau memodifikasi solusi Anda.
Palec
6

Dengan SQL Server 2012 dan seterusnya Anda dapat menggunakan FORMATfungsi ini

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

ini adalah salinan kode saya yang berfungsi memeriksanya, cara mengambil nama hari dari tanggal dalam sql

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

Jika Anda tidak ingin bergantung @@DATEFIRSTatau menggunakan DATEPART(weekday, DateColumn), hitung sendiri hari dalam seminggu.

Untuk minggu berbasis Senin (Eropa) paling sederhana adalah:

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

Untuk minggu berbasis Minggu (Amerika) gunakan:

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

Ini mengembalikan angka hari kerja (1 hingga 7) sejak 1 Januari masing-masing 7, 1753.

Michel de Ruiter
sumber
1

Anda dapat menggunakan DATEPART(dw, GETDATE())tetapi perlu diketahui bahwa hasilnya akan bergantung pada @@DATEFIRSTnilai pengaturan SQL server yang merupakan pengaturan hari pertama minggu (Di Eropa nilai default 7 yaitu hari Minggu).

Jika Anda ingin mengubah hari pertama dalam minggu ke nilai lain, Anda bisa menggunakan SET DATEFIRSTtetapi ini dapat memengaruhi di mana saja di sesi kueri yang tidak Anda inginkan.

Cara alternatif adalah dengan secara eksplisit menentukan nilai hari pertama minggu sebagai parameter dan menghindari tergantung pada @@DATEFIRSTpengaturan. Anda dapat menggunakan formula berikut untuk mencapainya saat membutuhkannya:

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

di mana @WeekStartDayadalah hari pertama dalam seminggu yang Anda inginkan untuk sistem Anda (dari 1 hingga 7 yang berarti dari Senin hingga Minggu).

Saya telah membungkusnya menjadi fungsi di bawah ini sehingga kami dapat menggunakannya kembali dengan mudah:

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

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

Ini sama dengan mengikuti (tetapi tidak tergantung pada pengaturan DATEFIRST SQL server):

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

Anda mungkin menemukan versi ini bermanfaat.

-- 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
sumber
1
Ini adalah kode tumpul, dan tidak menunjukkan indikasi apa yang sedang dilakukan atau dicapainya
brewmanz