日期时间上的Floor()函数-SQL Server

时间:2018-07-25 14:46:35

标签: sql sql-server datetime floor

http://sqlfiddle.com/#!18/639ec/2

CREATE TABLE TEST
(
ID INT,
OrderNo int,
DateReceived datetime
)

INSERT INTO TEST (ID,OrderNo,DateReceived)
VALUES ('1', '3454', '07-20-2018 00:00:00')

查询:

DECLARE @StartDate datetime,
@EndDate datetime,
@FlooredStart datetime ,
@FlooredEnd datetime 

SET @StartDate = '07-20-18'
SET @EndDate = '07-20-18'
SET @FlooredStart  = CAST(FLOOR(CAST(@startDate AS FLOAT)) AS DATETIME)
SET @FlooredEnd = DATEADD(d, 1, CAST(FLOOR(CAST(@endDate AS FLOAT)) AS DATETIME))

SELECT * FROM TEST 
WHERE DateReceived = @FlooredStart and DateReceived < @FlooredEnd

在我的实时版本中,如果收到的日期留为空白,则默认为该天的上午12:00:00。因此,对于此示例,如果我在07-20-18上搜索订单,它将不会返回在07-20-18的12:00:00 AM下达的订单。

所以我想在子句中添加> =

DECLARE @StartDate datetime,
@EndDate datetime,
@FlooredStart datetime ,
@FlooredEnd datetime 

SET @StartDate = '07-20-18'
SET @EndDate = '07-20-18'
SET @FlooredStart  = CAST(FLOOR(CAST(@startDate AS FLOAT)) AS DATETIME)
SET @FlooredEnd = DATEADD(d, 1, CAST(FLOOR(CAST(@endDate AS FLOAT)) AS 
DATETIME))

SELECT * FROM TEST 
-- WHERE DateReceived BETWEEN @StartDate AND @EndDate
WHERE DateReceived >= @FlooredStart and DateReceived < @FlooredEnd

结果:

| ID | OrderNo |         DateReceived |
|----|---------|----------------------|
|  1 |    3454 | 2018-07-20T00:00:00Z |

我只是想知道我的逻辑是否正确?谁能准确地向我解释floor()函数的作用。我知道它计算的是一年/月的第一天,但​​是这里需要吗?我在网上看了,却找不到任何地方的明确答案。

谢谢

1 个答案:

答案 0 :(得分:4)

不要使用floor来“截断”时间部分,而应使用仅日期的date类型:

DECLARE @StartDate date = '20180720', @EndDate date='20180720'

SELECT * FROM TEST 
WHERE cast(DateReceived date) between @startdate and @enddate

或者,仅一个日期:

SELECT * FROM TEST 
WHERE cast(DateReceived date) = @startdate 

请注意,我使用的是未分隔的日期文字。这是 only 唯一的日期格式。另一种明确的格式是日期时间类型的完整ISO8601格式。两位数的年份只是乞求,用于错误的解释方式。

cast(DateReceived date)datetime中的DateReceived值转换为date值。通常,将函数应用于字段是一个 bad 想法,因为这会阻止查询优化器使用任何索引。 SQL Server可以理解cast( ... as date)并进行转换:

cast(DateReceived date) = @startdate 

对于等于DateReceived between @startdate at 00:00 but before the next day at 00:00的范围查询,允许其使用DateReceived上的任何索引