รับวันในสัปดาห์ใน SQL Server 2005/2008


369

หากฉันมีวันที่ 01/01/2552 ฉันต้องการทราบว่าเป็นวันอะไรวันจันทร์อังคาร ฯลฯ

มีฟังก์ชันในตัวสำหรับสิ่งนี้ใน SQL Server 2005/2008 หรือไม่ หรือฉันจำเป็นต้องใช้ตารางเสริม?


1
หากคุณมีตารางที่มีการค้นหาบางส่วนของวันที่คุณมักจะทำอะไรผิดพลาด ฟังก์ชันวันที่ของ SQL Server นั้นมีมากมายและมีประสิทธิภาพดังนั้นข้อมูลใด ๆ ที่คุณต้องการแยกจากวันที่สามารถทำได้อย่างง่ายดายในคอลัมน์วันที่และเวลา
46432 Benjamin Autin

6
ตารางเสริมมีประโยชน์มากสำหรับการคำนวณวันที่มันไม่ได้เป็นเรื่องผิดปกติที่จะมีปฏิทินตารางเสริม ...

2
"มีประโยชน์สำหรับการคำนวณวันที่" เป็นที่น่าสงสัยอย่างมาก การคำนวณวันที่ส่วนใหญ่สามารถจัดการได้โดยไม่มีตารางเสริมใด ๆ และจะทำงานได้ดีขึ้นเช่นกัน ในบางกรณีตารางตัวเลขธรรมดาจะทำงานได้โดยไม่จำเป็นต้องใช้ตารางที่มีวันที่ตามจริง เหตุผลเดียวที่ฉันเห็นว่าตารางปฏิทินจริงที่จำเป็นคือเมื่อกฎที่เป็นวันทำงานและวันใดไม่ซับซ้อน สิ่งที่ฉันเห็นบ่อยเกินไปคือคนที่ใช้ตารางวันที่เพราะพวกเขาไม่รู้วิธีการอื่น จากนั้นพวกเขาจะต้องเติมตารางวันที่ทุก ๆ ครั้ง โง่.
ErikE

5
ฉันจะกินคำพูดของฉันถ้าคุณสามารถแสดงให้ฉันเห็นการใช้งานสำหรับตารางปฏิทินที่ 1) ไม่ใช่สำหรับกฎวันหยุด / วันทำงานที่ซับซ้อน 2) ไม่สามารถทำได้อย่างง่ายดายด้วยฟังก์ชั่นในตัวและ 3) ถ้าไม่ใช่ # 2 จากนั้นตาราง Numbers ก็ทำงานได้ดีเช่นกันและไม่จำเป็นต้องมีการเติมข้อมูลตารางด้วยวันที่ที่ระบุ
ErikE

2
คลังข้อมูลใช้ตารางปฏิทินอย่างกว้างขวาง เดือน, ไตรมาส, ปี ฯลฯ ที่ผ่านการคำนวณล่วงหน้าให้เขตข้อมูลแก่ผู้ใช้ปลายทางที่พวกเขาสามารถกรอง / รวมกับ
David Rushton

คำตอบ:


694

ใช้DATENAMEหรือDATEPART:

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

ขอบคุณฉันได้ลองใช้ชื่อไฟล์ แต่ใช้ d ทำให้ฉันกลับมาเป็นจำนวนเต็ม dw ใช้งานได้ตามที่คาดหวัง

39
นั่นเป็นเหตุผลที่ฉันต้องการใช้เลือกชื่อไฟล์ (วันทำงาน getdate ()) ฉันไม่ต้องจำไว้ว่า dw คืนวันธรรมดา .... เมื่อฉันสามารถใช้ "วันทำงาน" แทน
George Mastros

9
ทุกคน glancing กว่านี้ - ทราบว่าเริ่มต้นเริ่มต้นของสัปดาห์นี้เป็นวันอาทิตย์ ดูคำตอบของ @ Sung เพื่อดูวิธีการเปลี่ยนอย่างปลอดภัย
JonnyRaa

2
@niico เป็นเพราะดัชนี SQL ตั้งแต่วันที่ 1 ขณะที่ C ชอบดัชนีภาษาจาก 0
824276

95

แม้ว่าคำตอบของ SQLMenace นั้นได้รับการยอมรับ แต่ก็มีSETตัวเลือกที่สำคัญอย่างหนึ่งที่คุณควรระวัง

SET DATEFIRST

DATENAMEจะส่งคืนชื่อวันที่ที่ถูกต้องแต่จะไม่เป็นค่าDATEPARTเดียวกันหากวันแรกของสัปดาห์มีการเปลี่ยนแปลงตามที่แสดงด้านล่าง

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
ดังนั้นเพื่อให้ได้ค่า DatePart ( @@datefirst - 1 + datepart(weekday, thedate) ) % 7คงที่คุณทำ วันอาทิตย์จะเป็นศูนย์เสมอ
Endy Tjahjono

1
ค่อนข้างน่ากลัวสิ่งนี้เป็นแบบคงที่ดังนั้นคุณต้องทำตามต้นฉบับแบบสอบถามเปลี่ยนค่าเรียกใช้แบบสอบถามตั้งค่ารูปแบบเดิม
JonnyRaa

2
ส่วนหนึ่งที่ตลกของเรื่องนี้ก็คือ .NET ของDayOfWeekการแจงนับมีDayOfWeek.Sundayมีมูลค่า 0... ดังนั้นไม่ว่าสิ่งที่กำหนดไว้ค่าที่ส่งคืน SQL ที่ไม่ได้รับDateFirstการรักษาWEEKDAYจะไม่เข้ากันได้กับ. NET คู่กัน 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
คุณควรรู้ว่าเธอนั้นมีฟังก์ชั่นในตัวที่จะทำสิ่งเดียวกันให้สำเร็จ select datename(dw,getdate())
Soham Dasgupta

10
@SohamDasgupta ฟังก์ชันในตัวนี้ไม่ส่งคืนผลลัพธ์เดียวกันสำหรับ MS SQL รุ่นที่ไม่ใช่ภาษาอังกฤษ
นาย Scapegrace

12

เพื่อให้ได้ค่าที่กำหนดสำหรับวันของสัปดาห์สำหรับวันที่กำหนดคุณสามารถใช้การรวมกันของDATEPART ()และ@@ datefirst มิฉะนั้นคุณต้องพึ่งพาการตั้งค่าบนเซิร์ฟเวอร์

ลองดูเว็บไซต์ต่อไปนี้เพื่อดูคำตอบที่ดีกว่า: MS SQL: วันของสัปดาห์

วันของสัปดาห์จะอยู่ในช่วง 0 ถึง 6 โดยที่ 0 คือวันอาทิตย์, 1 คือวันจันทร์, ฯลฯ จากนั้นคุณสามารถใช้คำสั่งกรณีง่าย ๆ เพื่อส่งคืนชื่อวันทำงานที่ถูกต้อง


5
โปรดใส่คำตอบลงในคำตอบเพื่อให้ผู้คนไม่ต้องคลิกลิงค์เพื่อไปที่นั้น
Martin Smith

11

ยุโรป:

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

2
โปรดระบุคำอธิบายว่าโค้ดของคุณทำอะไรและตอบคำถามอย่างไร หากคุณได้รับข้อมูลโค้ดเป็นคำตอบคุณอาจไม่รู้ว่าต้องทำอย่างไร คำตอบควรให้คำแนะนำแก่ OP และผู้เยี่ยมชมในอนาคตเกี่ยวกับวิธีการแก้ไขข้อบกพร่องและแก้ไขปัญหา การชี้ให้เห็นว่าความคิดที่อยู่เบื้องหลังโค้ดของคุณคืออะไรช่วยอย่างมากในการทำความเข้าใจปัญหาและใช้หรือแก้ไขโซลูชันของคุณ
Palec


3

นี่เป็นสำเนาที่ใช้งานได้ของรหัสของฉันตรวจสอบวิธีการกู้คืนชื่อวันจากวันที่ใน 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

1

หากคุณไม่ต้องการพึ่งพา@@DATEFIRSTหรือใช้งานDATEPART(weekday, DateColumn)ให้คำนวณวันของสัปดาห์ด้วยตัวคุณเอง

สำหรับสัปดาห์ตามวันจันทร์ (ยุโรป) ที่ง่ายที่สุดคือ:

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

สำหรับการใช้งานในสัปดาห์วันอาทิตย์ (อเมริกา):

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

ส่งคืนหมายเลขวันทำงาน (1 ถึง 7) นับตั้งแต่วันที่ 1 มกราคมตามลำดับที่ 7, 1753


1

คุณสามารถใช้DATEPART(dw, GETDATE())แต่ระวังว่าผลลัพธ์จะขึ้นอยู่กับการตั้งค่าเซิร์ฟเวอร์ SQL @@DATEFIRSTซึ่งเป็นวันแรกของการตั้งค่าสัปดาห์ (ในยุโรปค่าเริ่มต้น 7 ซึ่งเป็นวันอาทิตย์)

หากคุณต้องการเปลี่ยนวันแรกของสัปดาห์เป็นค่าอื่นคุณสามารถใช้SET DATEFIRSTแต่สิ่งนี้อาจส่งผลกระทบทุกที่ในเซสชันการสืบค้นที่คุณไม่ต้องการ

ทางเลือกคือการระบุค่าวันแรกของสัปดาห์อย่างชัดเจนเป็นพารามิเตอร์และหลีกเลี่ยงขึ้นอยู่กับ@@DATEFIRSTการตั้งค่า คุณสามารถใช้สูตรต่อไปนี้เพื่อให้บรรลุผลเมื่อต้องการ:

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

ซึ่ง@WeekStartDayเป็นวันแรกของสัปดาห์ที่คุณต้องการสำหรับระบบของคุณ (1-7 ซึ่งหมายความว่าตั้งแต่วันจันทร์ถึงวันอาทิตย์)

ฉันได้ห่อมันไว้ข้างล่างฟังก์ชั่นเพื่อให้เราสามารถนำมาใช้ใหม่ได้อย่างง่ายดาย:

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

ตัวอย่างการใช้งาน: GetDayInWeek('2019-02-04 00:00:00', 1)

เทียบเท่ากับการติดตาม (แต่ไม่ขึ้นอยู่กับการตั้งค่า DATEFIRST ของเซิร์ฟเวอร์ SQL):

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

0

คุณอาจพบว่ารุ่นนี้มีประโยชน์

-- 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
นี่คือรหัสป้านและให้ข้อบ่งชี้ของสิ่งที่ทำหรือพยายามที่จะบรรลุไม่มี
brewmanz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.