日期时间的 Floor() 函数 - SQL 服务器

Floor() function on a datetime - SQL Server

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:00AM。因此对于这个例子,如果我在 07-20-18 搜索订单,它不会 return 放置在 07-20-18 12:00:00AM 的订单。

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

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() 函数在做什么。我知道它计算 year/month 的第一天,但​​这里需要吗?我在网上查了一下,到处都找不到明确的答案。

谢谢

不要使用 floor 到 "truncate" 时间部分,而是使用仅日期 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) 会将 DateReceived 中的 datetime 值转换为 date 值。通常,将函数应用于字段是一个 糟糕 的想法,因为它会阻止查询优化器使用任何索引。 SQL 服务器理解 cast( ... as date) 并转换 :

cast(DateReceived date) = @startdate 

相当于 DateReceived between @startdate at 00:00 but before the next day at 00:00 的范围查询,允许它使用 DateReceived

上的任何索引