查找不在该月的第一天或最后一天的日期

时间:2014-05-29 19:59:09

标签: sql sql-server sql-server-2008

我有一个名为Locations的表,其中有一个名为effective_date的列,其中包含多年的许多日期,我只想检索那些 而不是 < / strong>在该月的第一天或该月的最后一天。

4 个答案:

答案 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

希望这有帮助!