Tôi cần xác định số ngày trong tháng cho một ngày nhất định trong SQL Server.
Có chức năng tích hợp sẵn không? Nếu không, tôi nên sử dụng hàm do người dùng định nghĩa là gì?
Tôi cần xác định số ngày trong tháng cho một ngày nhất định trong SQL Server.
Có chức năng tích hợp sẵn không? Nếu không, tôi nên sử dụng hàm do người dùng định nghĩa là gì?
Câu trả lời:
Bạn có thể sử dụng như sau với ngày đầu tiên của tháng được chỉ định:
datediff(day, @date, dateadd(month, 1, @date))
Để làm cho nó hoạt động cho mọi ngày:
datediff(day, dateadd(day, 1-day(@date), @date),
dateadd(month, 1, dateadd(day, 1-day(@date), @date)))
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
day
thành phần của eomonth
đầu ra.
Trong SQL Server 2012, bạn có thể sử dụng EOMONTH (Transact-SQL) để lấy ngày cuối cùng của tháng và sau đó, bạn có thể sử dụng DAY (Transact-SQL) để lấy số ngày trong tháng.
DECLARE @ADate DATETIME
SET @ADate = GETDATE()
SELECT DAY(EOMONTH(@ADate)) AS DaysInMonth
Giải pháp thanh lịch nhất: hoạt động cho bất kỳ @DATE nào
DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@DATE),0)))
Ném nó vào một hàm hoặc chỉ sử dụng nó nội tuyến. Câu trả lời này trả lời câu hỏi ban đầu mà không có tất cả những thứ thừa trong các câu trả lời khác.
ví dụ cho ngày tháng từ các câu trả lời khác:
SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'1/31/2009'),0)))
Trả về 31
SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'2404-feb-15'),0)))
Trả về 29
SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'2011-12-22'),0)))
Trả về 31
--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)))
Cá nhân tôi mặc dù vậy, tôi sẽ tạo một UDF cho nó nếu không có chức năng tích hợp sẵn ...
Tôi sẽ đề nghị:
SELECT DAY(EOMONTH(GETDATE()))
--- 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()))
Giải pháp 1: Tìm số ngày trong tháng mà chúng ta hiện đang ở
DECLARE @dt datetime
SET @dt = getdate()
SELECT @dt AS [DateTime],
DAY(DATEADD(mm, DATEDIFF(mm, -1, @dt), -1)) AS [Days in Month]
Giải pháp 2: Tìm số ngày trong một tổ hợp tháng-năm nhất định
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]
Bạn cần thêm một hàm, nhưng đó là một hàm đơn giản. Tôi sử dụng cái này:
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
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]
Bạn cần tạo một hàm, nhưng nó là vì sự thuận tiện của riêng bạn. Nó hoạt động hoàn hảo và tôi chưa bao giờ gặp phải bất kỳ tính toán bị lỗi nào khi sử dụng chức năng này.
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
Cách hoạt động: trừ số ngày của ngày cho chính ngày đó sẽ cho bạn ngày cuối cùng của tháng trước. Vì vậy, bạn cần thêm một tháng vào ngày đã cho, trừ số ngày và nhận thành phần ngày của kết quả.
Tôi đã ủng hộ Mehrdad, nhưng điều này cũng hoạt động. :)
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
Để kiểm tra
declare @testDT datetime;
set @testDT = '2404-feb-15';
select dbo.GetDaysInMonth(@testDT)
đây là một số khác...
Select Day(DateAdd(day, -Day(DateAdd(month, 1, getdate())),
DateAdd(month, 1, getdate())))
Tôi biết câu hỏi này đã cũ nhưng tôi nghĩ tôi sẽ chia sẻ những gì tôi đang sử dụng.
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
và
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
Chúng có thể được kết hợp để tạo ra một hàm duy nhất để truy xuất số ngày trong tháng nếu cần.
SELECT DAY(SUBDATE(ADDDATE(CONCAT(YEAR(NOW()), '-', MONTH(NOW()), '-1'), INTERVAL 1 MONTH), INTERVAL 1 DAY))
Đẹp 'n' Đơn giản và không yêu cầu tạo bất kỳ chức năng nào
subdate
chức năng.
Câu trả lời của Mehrdad Afshari là câu trả lời chính xác nhất, ngoài thông thường, câu trả lời này dựa trên phương pháp toán học chính thức do Curtis McEnroe đưa ra trong blog của anh ấy 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
Để có được không. ngày trong tháng, chúng ta có thể sử dụng trực tiếp Day () có sẵn trong SQL.
Làm theo liên kết được đăng ở cuối câu trả lời của tôi cho SQL Server 2005/2008.
Ví dụ sau và kết quả là từ 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')
Kết quả trong SQL Server SSMS
(no column name)
1 31
Quá trình:
Khi sử dụng EOMONTH, bất kỳ định dạng ngày tháng nào chúng tôi sử dụng đều được chuyển đổi thành định dạng DateTime của SQL-server. Sau đó, đầu ra ngày của EOMONTH () sẽ là 2016-12-31 với 2016 là Năm, 12 là Tháng và 31 là Ngày. Kết quả này khi được chuyển vào Day (), nó sẽ cho bạn tổng số ngày trong tháng.
Nếu chúng tôi muốn nhận được kết quả tức thì để kiểm tra, chúng tôi có thể chạy trực tiếp đoạn mã dưới đây,
select DAY(EOMONTH(convert(datetime,'08/12/2016',103)))
hoặc là
select DAY(EOMONTH(convert(datetime,getdate(),103)))
để tham khảo cách làm việc trong SQL Server 2005/2008/2012, vui lòng theo liên kết bên ngoài sau ...
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';
kết quả: Tháng này 31
Tháng tới 30
DECLARE @m int
SET @m = 2
SELECT
@m AS [Month],
DATEDIFF(DAY,
DATEADD(DAY, 0, DATEADD(m, +@m -1, 0)),
DATEADD(DAY, 0, DATEADD(m,+ @m, 0))
) AS [Days in Month]
RETURN day(dateadd(month, 12 * @year + @month - 22800, -1))
select day(dateadd(month, 12 * year(date) + month(date) - 22800, -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)))
truy vấn đơn giản trong SQLServer2012:
chọn ngày (('20-05-1951 22:00:00'))
tôi đã kiểm tra nhiều ngày và nó luôn trả về một kết quả chính xác
select 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 + dateiff (dd, dateadd (dd, -1 * datepart (dd, getdate ()) + 1, getdate ()), dateadd (dd, -1 * datepart (dd, dateadd (mm, 1, getdate ())), dateadd (mm, 1, getdate ())))
thay thế bất kỳ ngày nào bằng getdate để lấy số tháng trong ngày cụ thể đó
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