给定datetime,按日期时间的月份过滤结果

时间:2016-10-13 17:52:13

标签: sql-server-2008

对于sql server 2008:过滤结果的最佳方法是什么,只返回与特定日期同月的结果?

我能想到的最好的是:

-- set up test data
DECLARE @TABLE1 AS TABLE (
    ID INT,
    STRING VARCHAR(MAX),
    DATECOLUMN DATETIME
)
INSERT INTO @TABLE1
SELECT
    0 ID,
    'TABLE1 0' STRING,
    CONVERT(DATETIME, '2016-10-13 12:45:00', 102) DATECOLUMN
UNION ALL SELECT 1, 'TABLE1 1', CONVERT(DATETIME, '2016-9-13 12:45:00', 102)
UNION ALL SELECT 2, 'TABLE1 2', CONVERT(DATETIME, '2016-10-1 00:00:00', 102)
UNION ALL SELECT 3, 'TABLE1 3', CONVERT(DATETIME, '2016-10-31 23:59:59', 102)

-- set up constraint
DECLARE @SOMEDATE DATETIME = CONVERT(DATETIME, '2016-10-13 12:45:00', 102)

-- filter
SELECT * FROM @TABLE1
WHERE MONTH(DATECOLUMN) = MONTH(@SOMEDATE)

这是最好的方式吗?

2 个答案:

答案 0 :(得分:1)

您的查询将返回DateColumn的月份与@SomeDate的月份匹配的记录,尽管(如@Jayvee指出的那样)无论年份如何都是如此。所以如果这就是你想要的,你的解决方案就没问题。

但你问这是否是最佳解决方案。我会说不,因为这不会利用您可能包含DateColumn的任何索引。

如果我在SQL Server 2008上,那么这就是我要做的事情:

 declare @someDate datetime  = GetDate()
 declare @startDate date
 declare @endDate date

 -- I want the first day of the month, at 12:00:00AM (no time component).
 -- The DateAdd expression subtracts days, and converting to the Date data type
 -- ensures that I don't have a time component hanging around.
 set @startDate = convert(date, DateAdd(day,- DatePart(day, @someDate) + 1, @someDate))

 -- I want the first day of the next month.  This is easy:
 set @endDate = DateAdd(month, 1, @startDate)

 -- Here's my actual query, that can take advantage of indexes that include DateColumn:
 select * 
 from   Table1
 where  DateColumn >= @startDate and DateColumn < @endDate

请注意,我说开始日期为>=,结束日期为<。这样可以确保我会在当月的最后一天获取具有非零时间组件的任何日期条目,但不会进入下个月。

答案 1 :(得分:0)

长期解决方案的最佳方法是创建日期维度表(您可以在那里找到脚本以自动生成一个)。日期调暗表将包含一个日期列表,包括日期前后的日期,它包括DayOfWeek,QuarterOfYear,YYYYMM等列,因此您可以将CAST(YOURDATE AS DATE)加入日期dim& #39;日期并提供漂亮的日期信息。在这里,您可以将两个表连接到日期暗淡并使用WHERE t1.YYYYMM = t2.YYYYMM。