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
这只是检查昨天的日期是否恰好在 baslangictarihi
和 bitistarihi
之间,包括两端。
只要理解像这样的谓词中的一切都是表达式。 CONVERT(date,GETDATE()-1)
表示没有时间部分的昨天。这两列是当时正在考虑的行中的任何值。如果左侧有一列,您知道这意味着什么,但这也不例外。它得到的评估是一样的。
正如其他人所解释的,这个有点古怪的条件检查昨天的日期 CONVERT(date,GETDATE()-1)
是否在两个日期字段 baslangictarihi
和 bitistarihi
之间。更重要的是,这样做不会阻止服务器使用任何涵盖 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 正确
下面的查询是什么意思?
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
这只是检查昨天的日期是否恰好在 baslangictarihi
和 bitistarihi
之间,包括两端。
只要理解像这样的谓词中的一切都是表达式。 CONVERT(date,GETDATE()-1)
表示没有时间部分的昨天。这两列是当时正在考虑的行中的任何值。如果左侧有一列,您知道这意味着什么,但这也不例外。它得到的评估是一样的。
正如其他人所解释的,这个有点古怪的条件检查昨天的日期 CONVERT(date,GETDATE()-1)
是否在两个日期字段 baslangictarihi
和 bitistarihi
之间。更重要的是,这样做不会阻止服务器使用任何涵盖 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 正确