仅基于月份和年份的SQL Server日期比较
我无法确定仅基于月和年来比较SQL中日期的最佳方法。仅基于月份和年份的SQL Server日期比较
我们根据日期进行计算,并且由于计费按月进行,因此月份的日期造成了更多的阻碍。
例如
DECLARE @date1 DATETIME = CAST('6/15/2014' AS DATETIME),
@date2 DATETIME = CAST('6/14/2014' AS DATETIME)
SELECT * FROM tableName WHERE @date1 <= @date2
因为@ DATE1比@ DATE2大于以上例子将不返回任何行。所以我想找一种方法来消除这个问题。
同样,出于同样的原因,下面的情况让我感到悲伤。
DECLARE @date1 DATETIME = CAST('6/14/2014' AS DATETIME),
@date2 DATETIME = CAST('6/15/2014' AS DATETIME),
@date3 DATETIME = CAST('7/1/2014' AS DATETIME)
SELECT * FROM tableName WHERE @date2 BETWEEN @date1 AND @date3
我已经完成了日期的内联转换,以获得指定日期的月份的第一天和最后一天。
SELECT *
FROM tableName
WHERE date2 BETWEEN
DATEADD(month, DATEDIFF(month, 0, date1), 0) -- The first day of the month for date1
AND
DATEADD(s, -1, DATEADD(mm, DATEDIFF(m, 0, date2) + 1, 0)) -- The lastday of the month for date3
必须有一个更简单的方法来做到这一点。有什么建议么?
为了处理不等式,比如之间,我喜欢将日期/时间转换为YYYYMM表示形式,无论是字符串还是整数。在这个例子中:
DECLARE @date1 DATETIME = CAST('6/14/2014' AS DATETIME),
@date2 DATETIME = CAST('6/15/2014' AS DATETIME),
@date3 DATETIME = CAST('7/1/2014' AS DATETIME);
SELECT * FROM tableName WHERE @date2 BETWEEN @date1 AND @date3;
我会写查询为:
SELECT *
FROM tableName
WHERE year(@date2) * 100 + month(@date2) BETWEEN year(@date1) * 100 + month(@date1) AND
year(@date3) * 100 + month(@date1);
SELECT *
FROM tableName
WHERE YEAR(@date1) = YEAR(@date2) AND MONTH(@date1) = MONTH(@date2)
你可以在给定日期的月份和年份过滤到当前日期,像这样:
SELECT *
FROM tableName
WHERE month(date2) = month(getdate()) and year(date2) = year(getdate())
只需更换用你想要的日期的GETDATE()
方法。
首先,我会使用一个格式是明确的日期,像标准'YYYYMMDD'
,而不是'6/15/2014'
你有一直在使用。阿龙贝特朗的博客解释远远比我更好,各个方面,这可能会出错:
Bad habits to kick : mis-handling date/range queries
对于具体问题,你该发现的第一个和个月的最后几天(为date1的最后一个查询和date3),在我看来是正确的。你只需要虽然月的第一天(DATE1下个月的DATE3的第一天的第一天),如果你避免邪恶BETWEEN
:What do BETWEEN and the devil have in common?
SELECT *
FROM tableName
WHERE date2 >= DATEADD(month, DATEDIFF(month, '19000101', @date1), '19000101')
AND date2 < DATEADD(month, 1+DATEDIFF(month, '19000101', @date3), '19000101') ;
的查询工作,因为它是,不管数据类型为date2
(DATE
,DATETIME
,DATETIME2
或SMALLDATTEIME
)。
加分点,date2
上的索引将被优化器这样考虑。
改进,根据(但不同)阿龙的博客文章,与DATEDIFF()
计算表达式时避免与基数估计的问题:
Performance Surprises and Assumptions : DATEDIFF
SELECT *
FROM tableName
WHERE date2 >= CONVERT(DATE, DATEADD(day, 1 - DAY(@date1), @date1))
AND date2 < DATEADD(month, 1,
CONVERT(DATE, DATEADD(day, 1 - DAY(@date3), @date3))) ;
的SQL Server版本? – christiandev 2014-10-07 15:39:16
@christiandev我们正在使用SQL 2008. – 2014-10-07 15:41:31
另外,如果您不使用时间部分,则可以使用'DATE'数据类型。 – christiandev 2014-10-07 15:45:56