我有一个名为Locations
的表,其中有一个名为effective_date
的列,其中包含多年的许多日期,我只想检索那些 而不是 < / strong>在该月的第一天或该月的最后一天。
答案 0 :(得分:4)
以下是SQL Fiddle Demo,详情如下。
生成表格和一些示例测试数据:
CREATE TABLE Locations(
effective_date DATETIME
)
INSERT INTO Locations
VALUES('2014-01-01') -- First day so we would expect this NOT to be returned
INSERT INTO Locations
VALUES('2014-01-02') -- This should be returned
INSERT INTO Locations
VALUES('2014-01-31') -- Last day of January so this should NOT be returned
然后,下面的查询计算出表中每个日期的月份的最后一天,仅当effective_date
不是计算的月份的第一天或最后一天时才返回记录。
SELECT effective_date FROM Locations
WHERE -- not the first day (the easy bit!)
DATEPART(day, effective_date) <> 1
-- not the last day (slightly more complex)
AND DATEPART(day, effective_date) <>
DATEPART(day, DATEADD(second,-1,DATEADD(month, DATEDIFF(month,0,effective_date)+1,0)))
执行时仅按预期返回January, 02 2014 00:00:00+0000
。
这里的聪明位是在给定日期时计算当月最后一天的功能,让我们检查并分解它:
DECLARE @sampleDate DATETIME
SET @sampleDate = '2014-01-02'
-- Calculate the number of months between '1900-01-01' and the @sampleDate
-- +1 as we want to shift into the following month so we can work back:
SELECT DATEDIFF(month,0,@sampleDate) + 1
-- Result --> 1369
-- Create a new date by adding the result of the previous step in
-- months to '1900-01-01'
SELECT DATEADD(month, DATEDIFF(month,0,@sampleDate)+1,0)
-- Result --> '2014-02-01' (giving first day of the following month)
-- Subtract one second from this
SELECT DATEADD(second,-1,DATEADD(month, DATEDIFF(month,0,@sampleDate)+1,0))
-- Result --> '2014-01-31 23:59:59' (giving the very end of the original month)
-- Finally extract the day of the month
SELECT DATEPART(day, DATEADD(second,-1,DATEADD(month, DATEDIFF(month,0,@sampleDate)+1,0)))
-- Result --> 31
答案 1 :(得分:1)
该月的第一天始终为1。
您应该能够对此进行调整以找到当月的最后一天:
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
来源:http://blog.sqlauthority.com/2007/08/18/sql-server-find-last-day-of-any-month-current-previous-next/
答案 2 :(得分:1)
如果effective_date
列的类型为date
,则此SQL查询将返回所有非空effective_date
值的行,该值不是第1天或最后一天月:
select t.effective_date , count(*)
from dbo.foo t
where 1 = 1 -- just for clarity
-- after the 1st day of the month
and t.effective_date > dateadd(day ,
1-day( t.effective_date ) ,
t.effective_date
)
-- and prior to the last day of the month
and t.effective_date < dateadd( day ,
-day( dateadd(month,1,t.effective_date) ) ,
dateadd(month,1,t.effective_date)
)
如果您的列中包含时间组件,即以下任何一个组件:
datetime
smalldatetime
datetime2
datetimeoffset
您希望覆盖您的基础并修改查询,例如
select *
from dbo.foo t
where 1=1 -- added for clarity
-- effective date on or after the 2nd of the month
and t.effective_date >= convert(date,
dateadd(day ,
2-day( t.effective_date ) ,
t.effective_date
)
)
-- and prior to the last day of the month
and t.effective_date < convert(date,
dateadd(day,
-day( dateadd(month,1,t.effective_date) ) ,
dateadd(month,1,t.effective_date)
)
)
答案 3 :(得分:0)
T-SQL仅在第一个和第一个时间显示一个月内的日期最后一天。同时显示除第一个和第二个之外的月份日期。最后一天。
declare @EndOfMonth as DateTime
set @EndOfMonth = ( SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0)) )
select @EndOfMonth as EndOfMonths
declare @EndOfMonthMinus1 as DateTime
set @EndOfMonthMinus1 = (SELECT DATEAdd(DAY, -1, @EndOfMonth) )
select @EndOfMonthMinus1 as EndOfMonths
declare @BeginingOfMonth as DateTime
set @BeginingOfMonth = (SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(GETDATE())-1),GETDATE()),101))
select @BeginingOfMonth as EndOfMonths
declare @BeginingOfMonthPlus1 as DateTime
set @BeginingOfMonthPlus1 = (SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(GETDATE())-2),GETDATE()),101))
select @BeginingOfMonthPlus1 as EndOfMonths
-- select dates in month exclude first and last day
SELECT TOP 1000 [effective_date]
FROM [Locations]
where effective_date <= @EndOfMonthMinus1
and effective_date >= @BeginingOfMonthPlus1
-- select only first of month and last of month
SELECT TOP 1000 [effective_date]
FROM [Locations]
where [effective_date]<= @EndOfMonth
and [effective_date] >= @EndOfMonthMinus1
and [effective_date] >= @BeginingOfMonth
and [effective_date] <= @BeginingOfMonthPlus1
希望这有帮助!