จะกำหนดจำนวนวันในหนึ่งเดือนใน SQL Server ได้อย่างไร?


97

ฉันต้องการกำหนดจำนวนวันในหนึ่งเดือนสำหรับวันที่กำหนดใน SQL Server

มีฟังก์ชันในตัวหรือไม่? ถ้าไม่ฉันควรใช้อะไรเป็นฟังก์ชันที่ผู้ใช้กำหนดเอง

คำตอบ:


116

คุณสามารถใช้สิ่งต่อไปนี้กับวันแรกของเดือนที่ระบุ:

datediff(day, @date, dateadd(month, 1, @date))

เพื่อให้ใช้งานได้ทุกวัน:

datediff(day, dateadd(day, 1-day(@date), @date),
              dateadd(month, 1, dateadd(day, 1-day(@date), @date)))

2
เช่นเดียวกับที่สแตนกล่าวว่าสิ่งนี้จะให้ผลลัพธ์ที่ไม่ถูกต้องในบางกรณี
ดีเจ

3
คุณไม่ได้หมายถึง: วันที่ (วัน, วันที่เพิ่ม (วัน, 1 วัน (@ วันที่), @ วันที่), วันที่เพิ่ม (เดือน, 1, วันที่เพิ่ม (วัน, 1 วัน (@ วันที่), วันที่)))
feihtthief

3
มันเป็นกรณีมุมที่หายาก แต่ฉันก็สะดุดมัน: นี่จะทำให้เกิดข้อผิดพลาดในเดือนธันวาคม 9999
Heinzi

1
สิ่งนี้ใช้ไม่ได้กับวันที่ใด ๆ ในเดือนธันวาคม 9999 คุณมีประเภทวันที่มากเกินไป สิ่งนี้ใช้ได้กับฉันใน SQL Server 2014: case when datediff(m, dateadd(day, 1-day(@date), @date), convert(date, convert(datetime, 2958463))) > 0 then datediff(day, dateadd(day, 1-day(@date), @date), dateadd(month, 1, dateadd(day, 1-day(@date), @date))) else 31 end
bradwilder31415

2
ทั้งหมดของการแก้ปัญหาดังกล่าวที่นี่อ่อนในการเปรียบเทียบกับความสง่างามของคำตอบ @Mikael Eriksson ของ ใช้งานได้เมื่อใดก็ตามที่มีการระบุวันที่ที่ถูกต้องโดยไม่มีวิธีแก้ปัญหาที่บ้าคลั่งสำหรับกรณีเฉพาะและเป็นรหัสที่ง่ายกว่ามาก - ฉันขอแนะนำให้ทุกคนใน T-SQL stick รับdayส่วนประกอบของeomonthผลลัพธ์
bsplosion

153

ใน SQL Server 2012 คุณสามารถใช้EOMONTH (Transact-SQL)เพื่อรับวันสุดท้ายของเดือนจากนั้นคุณสามารถใช้DAY (Transact-SQL)เพื่อรับจำนวนวันในเดือนนั้น

DECLARE @ADate DATETIME

SET @ADate = GETDATE()

SELECT DAY(EOMONTH(@ADate)) AS DaysInMonth

1
และถ้าคุณต้องการจำนวนวันในหนึ่งวันคุณสามารถใช้วิธี DATEFROMPARTS รหัสด้านบนจะกลายเป็นวันที่เลือก (EOMONTH (DATEFROMPARTS (@year, @month, 1))) AS DaysInMonth
nmariot

ความสวยงามของโซลูชันนี้เข้ามามีบทบาทหาก @ADate เป็นค่าที่คำนวณได้ซับซ้อน! +1
Stefan Steiger

ขอบคุณมาก!
Rejwanul Reja

28

โซลูชันที่หรูหราที่สุด: ใช้ได้กับทุกวันที่@DATE

DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@DATE),0)))

โยนมันในฟังก์ชั่นหรือใช้แบบอินไลน์ คำตอบนี้ตอบคำถามเดิมโดยไม่มีขยะเพิ่มเติมในคำตอบอื่น ๆ

ตัวอย่างวันที่จากคำตอบอื่น ๆ :

SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'1/31/2009'),0))) ผลตอบแทน 31

SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'2404-feb-15'),0))) ส่งคืน 29

SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'2011-12-22'),0))) ผลตอบแทน 31



12
--Last Day of Previous Month
SELECT DATEPART(day, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0)))

--Last Day of Current Month
SELECT DATEPART(day, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0)))

--Last Day of Next Month
SELECT DATEPART(day, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+2,0)))

โดยส่วนตัวแล้วฉันจะสร้าง UDF ให้หากไม่มีฟังก์ชันในตัว ...


5

ฉันจะแนะนำ:

SELECT DAY(EOMONTH(GETDATE()))

datepart ไม่ส่งคืนจำนวนวันและคำตอบของคุณก็ผิดด้วย
TheGameiswar

ทำงานให้ฉัน แต่แน่ใจว่าการใช้ฟังก์ชันวันจะเป็นคำตอบที่
ชัดเจนกว่า

2
คำตอบนี้เกือบจะเหมือนกับคำตอบด้านล่างด้วยคะแนนโหวต 75
Hila DG

3

รหัสนี้ทำให้คุณได้รับจำนวนวันในเดือนปัจจุบัน:

SELECT datediff(dd,getdate(),dateadd(mm,1,getdate())) as datas

เปลี่ยนgetdate()เป็นวันที่คุณต้องนับวัน


2
   --- sql server below 2012---
    select day( dateadd(day,-1,dateadd(month, 1, convert(date,'2019-03-01'))))
    -- this for sql server 2012--
    select day(EOMONTH(getdate()))

1

โซลูชันที่ 1: ค้นหาจำนวนวันในเดือนที่เราอยู่

DECLARE @dt datetime
SET     @dt = getdate()

SELECT @dt AS [DateTime],
       DAY(DATEADD(mm, DATEDIFF(mm, -1, @dt), -1)) AS [Days in Month]

โซลูชันที่ 2: ค้นหาจำนวนวันในคำสั่งผสมเดือน - ปีที่กำหนด

DECLARE @y int, @m int
SET     @y = 2012
SET     @m = 2

SELECT @y AS [Year],
       @m AS [Month],
       DATEDIFF(DAY,
                DATEADD(DAY, 0, DATEADD(m, ((@y - 1900) * 12) + @m - 1, 0)),
                DATEADD(DAY, 0, DATEADD(m, ((@y - 1900) * 12) + @m, 0))
               ) AS [Days in Month]

1

คุณจำเป็นต้องเพิ่มฟังก์ชัน แต่เป็นฟังก์ชันง่ายๆ ฉันใช้สิ่งนี้:

CREATE FUNCTION [dbo].[ufn_GetDaysInMonth] ( @pDate    DATETIME )

RETURNS INT
AS
BEGIN

    SET @pDate = CONVERT(VARCHAR(10), @pDate, 101)
    SET @pDate = @pDate - DAY(@pDate) + 1

    RETURN DATEDIFF(DD, @pDate, DATEADD(MM, 1, @pDate))
END

GO

1
การรวมกันของ DATEDIFF และ DATEADD ไม่ได้ผลเสมอไป หากคุณใส่วันที่ 31/1/2552 ลงไป DATEADD จะส่งคืน 2/28/2009 และ DATEDIFF จะให้คุณ 28 แทนที่จะเป็น 31

วิธีตรวจสอบฉันหมายถึงสิ่งที่ต้องดำเนินการเพื่อตรวจสอบวันในเดือน
hud

1
SELECT Datediff(day,
(Convert(DateTime,Convert(varchar(2),Month(getdate()))+'/01/'+Convert(varchar(4),Year(getdate())))),
(Convert(DateTime,Convert(varchar(2),Month(getdate())+1)+'/01/'+Convert(varchar(4),Year(getdate()))))) as [No.of Days in a Month]

1
select  datediff(day, 
        dateadd(day, 0, dateadd(month, ((2013 - 1900) * 12) + 3 - 1, 0)),
        dateadd(day, 0, dateadd(month, ((2013  - 1900) * 12) + 3, 0))
        )

Nice Simple และไม่ต้องสร้างฟังก์ชันใด ๆ Work Fine


1

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

CREATE FUNCTION [dbo].[get_days](@date datetime)
RETURNS int
AS
BEGIN
    SET @date = DATEADD(MONTH, 1, @date)
    DECLARE @result int = (select DAY(DATEADD(DAY, -DAY(@date), @date)))
    RETURN @result
END

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



0

ฉันโหวตให้ Mehrdad แต่มันก็ใช้ได้เช่นกัน :)

CREATE function dbo.IsLeapYear
(
    @TestYear int
)
RETURNS bit
AS
BEGIN
    declare @Result bit
    set @Result = 
    cast(
        case when ((@TestYear % 4 = 0) and (@testYear % 100 != 0)) or (@TestYear % 400 = 0)
        then 1
        else 0
        end
    as bit )
    return @Result
END
GO

CREATE FUNCTION dbo.GetDaysInMonth
(
    @TestDT datetime
)
RETURNS INT
AS
BEGIN

    DECLARE @Result int 
    DECLARE @MonthNo int

    Set @MonthNo = datepart(m,@TestDT)

    Set @Result = 
    case @MonthNo
        when  1 then 31
        when  2 then 
            case 
                when dbo.IsLeapYear(datepart(yyyy,@TestDT)) = 0
                then 28
                else 29
            end
        when  3 then 31
        when  4 then 30
        when  5 then 31
        when  6 then 30
        when  7 then 31
        when  8 then 31
        when  9 then 30 
        when 10 then 31
        when 11 then 30 
        when 12 then 31
    end

    RETURN @Result
END
GO

ทดสอบ

declare @testDT datetime;

set @testDT = '2404-feb-15';

select dbo.GetDaysInMonth(@testDT)


0

ฉันรู้ว่าคำถามนี้เก่า แต่ฉันคิดว่าจะแบ่งปันสิ่งที่ฉันใช้

DECLARE @date date = '2011-12-22'

/* FindFirstDayOfMonth - Find the first date of any month */
-- Replace the day part with -01
DECLARE @firstDayOfMonth date = CAST( CAST(YEAR(@date) AS varchar(4)) + '-' + 
                                      CAST(MONTH(@date) AS varchar(2)) + '-01' AS date)
SELECT @firstDayOfMonth

และ

DECLARE @date date = '2011-12-22'

/* FindLastDayOfMonth - Find what is the last day of a month - Leap year is handled by DATEADD */
-- Get the first day of next month and remove a day from it using DATEADD
DECLARE @lastDayOfMonth date = CAST( DATEADD(dd, -1, DATEADD(mm, 1, FindFirstDayOfMonth(@date))) AS date)

SELECT @lastDayOfMonth

สิ่งเหล่านี้สามารถรวมกันเพื่อสร้างฟังก์ชันเดียวเพื่อดึงจำนวนวันในหนึ่งเดือนหากจำเป็น


0
SELECT DAY(SUBDATE(ADDDATE(CONCAT(YEAR(NOW()), '-', MONTH(NOW()), '-1'), INTERVAL 1 MONTH), INTERVAL 1 DAY))

Nice 'n' เรียบง่ายและไม่ต้องสร้างฟังก์ชันใด ๆ


สำหรับ SQL Server; ฉันไม่เคยได้ยินเกี่ยวกับsubdateฟังก์ชัน
LittleBobbyTables - Au Revoir

0

การตอบกลับของ Mehrdad Afshari นั้นแม่นยำที่สุดนอกเหนือจากปกติคำตอบนี้จะขึ้นอยู่กับวิธีการทางคณิตศาสตร์อย่างเป็นทางการของ Curtis McEnroe ในบล็อกของเขาhttps://cmcenroe.me/2014/12/05/days-in-month-formula.html

DECLARE @date  DATE= '2015-02-01'
DECLARE @monthNumber TINYINT 
DECLARE @dayCount TINYINT
SET @monthNumber = DATEPART(MONTH,@date )
SET @dayCount = 28 + (@monthNumber + floor(@monthNumber/8)) % 2 + 2 %    @monthNumber + 2 * floor(1/@monthNumber)   
SELECT @dayCount + CASE WHEN @dayCount = 28 AND DATEPART(YEAR,@date)%4 =0 THEN 1 ELSE 0 END -- leap year adjustment

0

เพื่อรับเลขที่ ของวันในหนึ่งเดือนเราสามารถใช้ Day () ที่มีอยู่ใน SQL ได้โดยตรง

ไปที่ลิงค์ที่โพสต์ไว้ท้ายคำตอบของฉันสำหรับ SQL Server 2005/2008

ตัวอย่างและผลลัพธ์ต่อไปนี้มาจาก SQL 2012

alter function dbo.[daysinm]
(
@dates nvarchar(12)
)
returns int
as
begin
Declare @dates2 nvarchar(12)
Declare @days int
begin
select @dates2 = (select DAY(EOMONTH(convert(datetime,@dates,103))))
set @days = convert(int,@dates2)
end
return @days
end

--select dbo.daysinm('08/12/2016')

ผลลัพธ์ใน SQL Server SSMS

  (no column name)
1 31

กระบวนการ:

เมื่อใช้ EOMONTH รูปแบบวันที่ที่เราใช้จะถูกแปลงเป็นรูปแบบ DateTime ของ SQL-server จากนั้นผลลัพธ์วันที่ของ EOMONTH () จะเป็น 2016-12-31 โดยมี 2016 เป็นปี 12 เป็นเดือนและ 31 เป็นวัน ผลลัพธ์นี้เมื่อส่งผ่านไปยัง Day () จะให้จำนวนวันทั้งหมดในเดือนนั้น

หากเราต้องการรับผลทันทีสำหรับการตรวจสอบเราสามารถเรียกใช้โค้ดด้านล่างได้โดยตรง

select DAY(EOMONTH(convert(datetime,'08/12/2016',103)))

หรือ

select DAY(EOMONTH(convert(datetime,getdate(),103)))

สำหรับการอ้างอิงการทำงานใน SQL Server 2005/2008/2012 โปรดไปที่ลิงค์ภายนอกต่อไปนี้ ...

ค้นหาจำนวนวันในหนึ่งเดือนใน SQL


0
DECLARE @date DATETIME = GETDATE(); --or '12/1/2018' (month/day/year) 
SELECT DAY(EOMONTH ( @date )) AS 'This Month'; 
SELECT DAY(EOMONTH ( @date, 1 )) AS 'Next Month';

ผลลัพธ์: 31 เดือนนี้

เดือนหน้า 30


สิ่งนี้ไม่ส่งคืนจำนวนวันในเดือน
ashleedawg

ใช่. แต่สำหรับ SQL Server 2012 ขึ้นไป
Alberto Cláudio Mandlate




-1
DECLARE @date nvarchar(20)
SET @date ='2012-02-09 00:00:00'
SELECT DATEDIFF(day,cast(replace(cast(YEAR(@date) as char)+'-'+cast(MONTH(@date) as char)+'-01',' ','')+' 00:00:00' as datetime),dateadd(month,1,cast(replace(cast(YEAR(@date) as char)+'-'+cast(MONTH(@date) as char)+'-01',' ','')+' 00:00:00' as datetime)))

-1

แบบสอบถามง่ายๆใน SQLServer2012:

เลือกวัน (('20-05-1951 22:00:00'))

ฉันทดสอบมาหลายวันแล้วและส่งคืนผลลัพธ์ที่ถูกต้องเสมอ


2
SELECT DAY (CAST ('1951-05-20' AS DATE)) ส่งคืน 20 ซึ่งเป็นส่วนของวันของวันที่ จะไม่ส่งคืนจำนวนวันในเดือนพฤษภาคม
แม้เมี่ยน

-1

เลือก first_day = dateadd (dd, -1 * datepart (dd, getdate ()) + 1, getdate ()), last_day = dateadd (dd, -1 * datepart (dd, dateadd (mm, 1, getdate ())) , dateadd (mm, 1, getdate ())), no_of_days = 1 + วันที่ (dd, dateadd (dd, -1 * datepart (dd, getdate ()) + 1, getdate ()), dateadd (dd, -1 * datepart (dd, dateadd (mm, 1, getdate ())), dateadd (mm, 1, getdate ())))

แทนที่วันที่ใด ๆ ด้วย getdate เพื่อรับจำนวนเดือนในวันที่นั้น ๆ


-1
DECLARE @Month INT=2,
    @Year INT=1989
DECLARE @date DateTime=null
SET @date=CAST(CAST(@Year AS nvarchar) + '-' + CAST(@Month AS nvarchar) + '-' + '1' AS DATETIME);

DECLARE @noofDays TINYINT 
DECLARE @CountForDate TINYINT
SET @noofDays = DATEPART(MONTH,@date )
SET @CountForDate = 28 + (@noofDays + floor(@noofDays/8)) % 2 + 2 %    @noofDays + 2 * floor(1/@noofDays)   
SET @noofDays= @CountForDate + CASE WHEN @CountForDate = 28 AND DATEPART(YEAR,@date)%4 =0 THEN 1 ELSE 0 END
PRINT @noofDays

1
สวัสดีและยินดีต้อนรับสู่ SO! แม้ว่ารหัสอาจพูดเองการให้รายละเอียดบางอย่างจะช่วยปรับปรุงคุณภาพของคำตอบของคุณ!
mrun
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.