ฉันจะเลือกวันแรกของเดือนใน SQL ได้อย่างไร


308

ฉันแค่ต้องเลือกวันแรกของเดือนของตัวแปร datetime ที่กำหนด

ฉันรู้ว่ามันง่ายที่จะใช้รหัสประเภทนี้:

select CAST(CAST(YEAR(@mydate) AS VARCHAR(4)) 
+ '/' + CAST(MONTH(@mydate) AS VARCHAR(2)) + '/01' AS DATETIME)

แต่นี่ไม่ได้สวยงามมากและอาจไม่เร็วนักเช่นกัน

มีวิธีที่ดีกว่าในการทำเช่นนี้? ฉันใช้ SQL Server 2008

คำตอบ:


604
SELECT DATEADD(month, DATEDIFF(month, 0, @mydate), 0) AS StartOfMonth


63
ควรสังเกตว่าข้อผิดพลาดที่ระบุโดย Martin Smith สามารถ "เท่านั้น" ส่งผลต่อประสิทธิภาพไม่ใช่ความถูกต้อง
Olson.dev

14
นี่คือคำอธิบายเกี่ยวกับสาเหตุและวิธีการทำงานนี้
RubberDuck

34
ในกรณีที่มีคนสงสัยว่าSELECT EOMONTH(@mydate) AS EndOfMonthจะให้วันสุดท้ายของเดือน
hallizh

3
ฉันจะทราบได้อย่างไรว่าข้อผิดพลาดในการประมาณความผิดพลาดที่บันทึกไว้จะมีผลกับฉันหรือไม่ มันถูกทำเครื่องหมายเป็นคงที่ในปี 2010 นั่นหมายความว่าเฉพาะ SQL Server 2012 และใหม่กว่านั้นปลอดภัยหรือเป็นไปได้ว่าเซิร์ฟเวอร์ 2008 อาจได้รับการแก้ไขแล้วหรือไม่?
Jon

134

นอกจากคำตอบข้างต้นทั้งหมดแล้วยังมีวิธีที่อิงจากฟังก์ชั่นที่แนะนำ sql 2012

SELECT DATEFROMPARTS(YEAR(@mydate),MONTH(@mydate),1)

63

เริ่มต้นด้วย SQL Server 2012:

SELECT DATEADD(DAY,1,EOMONTH(@mydate,-1))

11
ดูเหมือนว่าจะใช้งานได้เฉพาะในปี 2012 และหลังจากนั้น msdn.microsoft.com/en-us/library/hh213020.aspx
Josh Yeager

1
มีข้อได้เปรียบที่กล่าวถึงวันที่ของแหล่งข้อมูลเพียงครั้งเดียวดังนั้น neater หากได้รับมาจากการเรียกใช้ฟังก์ชัน
Ian Horwill

14

การคัดเลือกสตริง (เช่น "5/1/2009") ไปยังวันที่และเวลานั้นชัดเจนกว่า แต่เราพบโค้ดในขณะที่ย้อนกลับไปซึ่งจะส่งคืนเดือนแรกของเดือน ...

DECLARE @Date DATETIME
//...
SELECT DATEADD(mm, DATEDIFF(mm,0,@Date), 0)


6

มันอาจจะค่อนข้างเร็ว ทำไมไม่สร้างมันเป็นฟังก์ชั่น sql

CREATE FUNCTION [dbo].[GetFirstDayOfMonth] ( @InputDate    DATETIME )
RETURNS DATETIME
BEGIN

    RETURN CAST(CAST(YEAR(@InputDate) AS VARCHAR(4)) + '/' + 
                CAST(MONTH(@InputDate) AS VARCHAR(2)) + '/01' AS DATETIME)

END
GO


3

โปรดใช้สิ่งนี้

  1. สำหรับเซิร์ฟเวอร์ 2012

    DATEFROMPARTS(year('2015-06-30'),month('2015-06-30'),1)
  2. ก่อน Server 2012

    select  cast(cast(year('2015-06-30') as varchar(4))+'-'+ cast(month('2015-06-30') as varchar(2))+'-01' as smalldatetime)

3

วันแรกและวันสุดท้ายของเดือนปัจจุบัน:

select dateadd(mm, -1,dateadd(dd, +1, eomonth(getdate()))) as FirstDay, 
eomonth(getdate()) as LastDay

2
SELECT @myDate - DAY(@myDate) + 1

ทางออกที่ง่ายและสง่างามจริง ๆ แต่โปรดจำไว้ว่านี่จะส่งคืนส่วนเวลาของวันที่เช่นกันหากระบุไว้ในตัวแปร
kuklei

ฉันทำงานนี้ไม่ได้ Operand type clash: date is incompatible with intนอกจากวงเล็บปิดพิเศษที่ฉันได้รับข้อผิดพลาดนี้: ฉันเดาว่าเป็นเพราะคุณกำลังพยายามใช้ตัว-ดำเนินการในวันที่หรือไม่
Sam

ฉันไม่รู้ว่ามันดีแค่ไหนในแง่ของประสิทธิภาพ แต่มันก็ทำงานได้อย่างแน่นอน
salcoin

@Sam คุณได้รับผลกระทบเนื่องจากการคำนวณทางคณิตศาสตร์อย่างง่าย (+, -) ทำงานบนชุดข้อมูลไม่ใช่วันที่
darlove

2
----Last Day of Previous Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))
LastDay_PreviousMonth
----Last Day of Current Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
LastDay_CurrentMonth
----Last Day of Next Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+2,0))
LastDay_NextMonth

แต่ OP กำลังมองหาวันแรกของเดือน สำหรับวันสุดท้ายคุณสามารถใช้ EOMONTH () - เป็นแบบนี้มาตั้งแต่ปี 2012
deutschZuid

2

นี่อาจเป็นฟังก์ชั่นใหม่ แต่คุณยังสามารถใช้ฟังก์ชั่นเก่าได้:

select DATEFROMPARTS(year(@mydate),month(@mydate),'01')

ถ้าวันที่ในตัวแปรเป็นตัวอย่าง'2017-10-29' มันจะส่งคืนวันที่'2017-10-01'

https://docs.microsoft.com/en-us/sql/t-sql/functions/datefromparts-transact-sql?view=sql-server-ver15


1

ผู้ใช้ Google ในอนาคตลองใช้สิ่งนี้:

select date_sub(ref_date, interval day(ref_date)-1 day) as day1;

3
นี่คือsql-serverคำถามdate_subและมีinterval mysql
OGHaza

ดีจุดฉันแก้ไขคำตอบ ฉันคิดว่ามันยังคงเกี่ยวข้องกับเธรด
Ariel T

1

ฉันใช้ GETDATE () เป็นวันที่ที่จะทำงานคุณสามารถแทนที่ด้วยวันที่ที่คุณต้องการ
นี่คือวิธีการทำงาน: ก่อนอื่นเราจัดรูปแบบวันที่ใน YYYYMMDD ... รูปแบบตัดทอนเพื่อเก็บอักขระที่เหลือเพียง 6 ตัวเพื่อเก็บไว้ในส่วนของ YYYYMM จากนั้นผนวก '01' เป็นเดือน - และ voila! คุณมีวันแรกของเดือนปัจจุบัน

SELECT CAST(CONVERT(VARCHAR(6),GETDATE(),112) +'01' AS DATETIME) AS StartOfMonth

BTW ประสิทธิภาพดีเยี่ยมในเรื่องนี้!


1

หากคุณกำลังมองหาสิ่งนี้ในวันนี้และการใช้ SQL Server 2012 หรือใหม่กว่าคุณมีฟังก์ชัน EOMONTH ซึ่งทำให้ง่ายขึ้น:

SELECT DATEADD(day, 1, EOMONTH(DATEADD(month, -1, GETDATE()))) as firstdateofmonth

คุณสามารถเปลี่ยน GETDATE () ด้วยตัวแปรวันที่ใดก็ได้ที่คุณต้องการ


1

ที่นี่เราสามารถใช้แบบสอบถามด้านล่างเพื่อวันแรกของเดือนและวันสุดท้ายของเดือน

SELECT DATEADD(DAY,1,EOMONTH(Getdate(),-1)) as 'FD',Cast(Getdate()-1 as Date)
as 'LD'


1
DECLARE @startofmonth date
SET @startofmonth = DATEADD(dd,1,EOMONTH(Getdate(),-2))

วันที่ -2 คุณจะได้รับวันแรกของเดือนที่แล้ว เช่น getdate () คือ 10/15/18 ผลลัพธ์ของคุณจะเป็น 9/1/18 เปลี่ยนเป็น -1 และผลลัพธ์ของคุณจะเป็น 10/1/18 0 จะเป็นจุดเริ่มต้นของเดือนถัดไป 11/1/2018 ฯลฯ ฯลฯ

หรือ

DECLARE @startofmonth date
SET @startofmonth = DATEADD(dd,1,EOMONTH(@mydate,-1))

1

ลองเรียกใช้คิวรีต่อไปนี้:

SELECT DATE_ADD(DATE_ADD(LAST_DAY(CURRENT_DATE-INTERVAL 1 DAY),INTERVAL 1 DAY),INTERVAL -1 MONTH)


0

เลือก CONVERT (วันที่ DATEADD (dd - - DATEPART (dd, getdate ()) - 1), getdate ()), 120)

ฟังก์ชั่นนี้จะให้ส่วนวันที่ของวันที่เริ่มต้นของเดือน


0
SELECT DATEADD (DAY, -1 * (DAY(GETDATE()) - 1), GETDATE())

.................................................. ...................

หากคุณไม่ต้องการเวลาให้แปลงเป็น DATE หรือถ้าต้องการให้เป็นเวลา 0:00:00 ให้แปลงเป็น DATE แล้วกลับไปเป็น DATETIME

SELECT CONVERT (DATETIME,  
CONVERT (DATE, DATEADD (DAY, -1 * (DAY(GETDATE()) - 1),
GETDATE())))

เปลี่ยน GETDATE () เป็นวันที่คุณต้องการ


0

ฉันส่วนตัวแนะนำว่า sql ด้านล่างเพราะเมื่อฉันลองใช้ฟังก์ชั่นวันที่ในเงื่อนไขข้อมันช้าลงความเร็วแบบสอบถามของฉันมาก

อย่างไรก็ตามโปรดลองใช้สิ่งนี้

select CONCAT(DATEPART(YYYY,@mydate),'-',DATEPART(MM,@mydate),'-01')

0

ที่จะไม่แข่งขันกับจิตใจที่ยิ่งใหญ่ใด ๆ ที่นี่ แต่คำแนะนำง่ายๆแตกต่างกันเล็กน้อยว่าคำตอบที่ได้รับการยอมรับข้างต้น

select dateadd(day, -(datepart(day,@date)+1,@date)

0

ฉันชอบที่จะใช้FORMATคุณยังสามารถระบุเวลา

SELECT FORMAT(@myDate,'yyyy-MM-01 06:00') first_of_a_month



0

สำหรับทุกคนที่ยังคงมองหาคำตอบนี้ทำงานเหมือนมีมนต์ขลังและจะไปกับ dateadds ใด ๆ การประทับเวลาเป็นทางเลือกในกรณีที่จำเป็นต้องระบุ แต่ใช้งานได้โดยไม่ต้องใช้เช่นกัน

SELECT left(convert(varchar, getdate(),23),7)+'-01 00:00:00'

0

รับวันที่แรกและวันที่สุดท้ายในวันที่เราผ่านเป็นพารามิเตอร์ใน SQL

     @date DATETIME
    SELECT @date = GETDATE()
    SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(@date)-1),@date),105) AS value,
    'First Day of Current Month' AS name
    UNION
    SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(DATEADD(mm,1,@date))),
    DATEADD(mm,1,@date)),105),
    'Last Day of Current Month'
    GO


      **OutPut**

12/01/2019  First Day of Current Month
12/31/2019  Last Day of Current Month

-3

นี่คือวิธีที่คุณจะทำใน MySQL:

  select DATE_FORMAT(NOW(), '%Y-%m-1')

4
โปรดระบุว่านี่ไม่ใช่คำตอบของ sql-server แต่ใช้ได้กับ MySQL เท่านั้น
kuklei

สำหรับ SQL Server คุณสามารถใช้SELECT FORMAT(GETDATE(), 'yyyy-MM-01')
NASSER

อย่าสนับสนุนให้ผู้ใช้จัดรูปแบบวันที่เป็นสตริงเพื่อทำสิ่งที่สามารถทำได้และควรทำตัวเลข มันเหมือนกับการพูดว่า "คุณสามารถปัดเศษตัวเลขลงเป็น 100 ที่ใกล้เคียงที่สุดโดยจัดรูปแบบเป็นสตริงซับสตริงทั้งหมดยกเว้นตัวเลขสองหลักสุดท้ายปิดและเชื่อมต่อกับ '00'"
Caius Jard
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.