SQL 服务器:在 getdate 之间使用

SQL Server: Using between with getdate

下面的查询是什么意思?

CONVERT(date,GETDATE()-1) between d.baslangictarihi and d.bitistarihi

我知道如何通过首先选择列名然后给出值来使用 between 。但是这里是先赋值再调用2列。

你可以“分解”BETWEEN 表达式,这样:

CONVERT(date, GETDATE() - 1) BETWEEN d.baslangictarihi AND d.bitistarihi

变成这样:

CONVERT(date, GETDATE() - 1) >= d.baslangictarihi AND
CONVERT(date, GETDATE() - 1) <= d.bitistarihi

这只是检查昨天的日期是否恰好在 baslangictarihibitistarihi 之间,包括两端。

只要理解像这样的谓词中的一切都是表达式。 CONVERT(date,GETDATE()-1) 表示没有时间部分的昨天。这两列是当时正在考虑的行中的任何值。如果左侧有一列,您知道这意味着什么,但这也不例外。它得到的评估是一样的。

正如其他人所解释的,这个有点古怪的条件检查昨天的日期 CONVERT(date,GETDATE()-1) 是否在两个日期字段 baslangictarihibitistarihi 之间。更重要的是,这样做不会阻止服务器使用任何涵盖 baslangictarihi bitistarihi.

的索引

索引是根据实际存储的值创建的,因此将函数应用于字段可以防止服务器使用索引来加快搜索速度。

因此,虽然 baslangictarihi <= GETDATE() 可以使用覆盖该字段的任何索引来将处理仅限于匹配的 table 行,但 dateadd(d,1,baslangictarihi) <= GETDATE() 必须处理所有 table 行, 计算结果并将其与 GETDATE() 进行比较。在大型 table 中,这可能会非常慢。

SQL 服务器日期怪癖

第一部分也有一些怪癖,因为 SQL 服务器的日期支持有些怪异。公平地说,所有 数据库和编程语言在日期方面都有怪癖。

GETDATE() returns 遗留 datetime 类型,通常表现为浮点数,整数部分是 1899-12-30 的偏移量(没有错字,确实是十二月30), 小数代表时间。这就是 1990 年代 Visual Basic 中日期的存储方式 Excel (OADate format)

由于GETDATE()作为浮点数,可以通过减去整数来减去天数,所以GETDATE()-1等价于DATEADD('d',GETDATE(),-1).

SQL 服务器没有间隔类型,所以在一些古怪的代码中你甚至会看到人们将 intervals 存储为 datetime,例如 0000-00-01 01:00 并直接添加两个日期。 None 2005 年引入的“新”日期类型 (datetime2,datetimeoffset,date) 允许这样做。

最后,convert(date,....)datetime 转换为 date,一种仅包含日期的类型。实际上,这会截断 GETDATE()

返回的时间部分

没有怪癖的相同表达式将是 CONVERT(date,DATEADD(d,-1,GETDATE()))

让我们考虑一个示例数据以更好地理解这一点。

membership_dim

id name dob membership_start_date membership_end_date
1 abc 19-05-1976 01-05-2020 31-12-2022
2 efg 10-01-1990 21-01-2018 31-12-2021
3 xyz 31-01-1990 12-01-2022 31-12-2022

Your Query

CONVERT(date,GETDATE()-1) between d.baslangictarihi and d.bitistarihi

重写以匹配上述示例数据

select * from membership_dim where CONVERT(date,GETDATE()-1) between membership_start_date and membership_end_date

Result set

id name dob membership_start_date membership_end_date
1 abc 19-05-1976 01-05-2020 31-12-2022
3 xyz 31-01-1990 12-01-2022 31-12-2022

Explanation:

让我们分解代码

CONVERT(日期,GETDATE()-1)

-> getdate()-1 = returns 日期时间格式的昨天日期 (01-23-2022 xx:xx:xx.xxx)

-> convert = 将数据时间转换为日期 (01-23-2022)

-> between = 比较运算符

01-23-2022 在 01-05-2020 和 31-12-2022 之间 - returns true

01-23-2022 在 21-01-2018 和 31-12-2021 之间 - returns 错误

01-23-2022 在 21-01-2018 和 31-12-2022 之间 - returns 正确