通过比较时间范围获取要存储到临时 table 中的正确数据
Getting the correct data to be stored into temp table by comparing timerange
目前,我需要将正确的数据输入到 temp table。我需要比较 3 个日期时间。但是,并非所有值都已填充。
示例-假设所有日期都相同
数据1
日期时间1
日期时间2
日期时间3
第一个
2020-08-24 14:00:00.000
2020-08-24 14:30:00.000
2020-08-24 15:30:00.000
第二
空
2020-08-24 13:00:00.000
2020-08-24 14:30:00.000
第三
空
空
2020-08-24 10:00:00.000
从示例中可以看出,列中有一些空值。我需要先获取DateTime1的值,如果为null则获取DateTime2的值。如果 DateTime2 也为 null,则得到 DateTime3.
取值后,我需要比较一下,看是否少于2小时,然后再放入临时table。
示例,如果当前时间是下午 2 点 = 1400 小时
我要显示的最终输出
数据1
日期时间1
日期时间2
日期时间3
第一个
2020-08-24 14:00:00.000
2020-08-24 14:30:00.000
2020-08-24 15:30:00.000
第二
空
2020-08-24 13:00:00.000
2020-08-24 14:30:00.000
听起来您想 select 在过去两个小时内具有日期时间字段的行。您不能使用像 COALESCE
这样的函数,因为那样会阻止使用任何覆盖列的索引。如果您使用例如:
WHERE COALESCE(DateTime1,DateTime2,DateTime3) >DATEADD(HOUR,-2,GETDATE())
服务器将无法使用任何覆盖日期字段的索引,并且将被迫扫描整个 table 以评估函数输出和过滤条件
一个简单的 WHERE
应该可以工作,甚至不检查 NULL
,因为与 NULL
的任何比较都失败了:
declare @cutoff datetime=DATEADD(HOUR,-2,GETDATE())
SELECT .....
WHERE
DateTime1 > @cutoff
OR DateTime2 > @cutoff
OR DateTime3 > @cutoff
如果您只想比较 time 部分,唯一有效的方法是使用 time
类型将时间部分提取到单独的字段中并对其进行索引.使用 提取时间部分,例如 cast(DateTime1 as time)
将阻止使用索引。
以下条件将通过扫描整个 table 来工作:
declare @cutoff time=cast(DATEADD(HOUR,-2,GETDATE()) as time);
SELECT ...
WHERE cast(COALESCE(DateTime1,DateTime2,DateTime3) as time) > @cutoff
目前,我需要将正确的数据输入到 temp table。我需要比较 3 个日期时间。但是,并非所有值都已填充。
示例-假设所有日期都相同
数据1 | 日期时间1 | 日期时间2 | 日期时间3 |
---|---|---|---|
第一个 | 2020-08-24 14:00:00.000 | 2020-08-24 14:30:00.000 | 2020-08-24 15:30:00.000 |
第二 | 空 | 2020-08-24 13:00:00.000 | 2020-08-24 14:30:00.000 |
第三 | 空 | 空 | 2020-08-24 10:00:00.000 |
从示例中可以看出,列中有一些空值。我需要先获取DateTime1的值,如果为null则获取DateTime2的值。如果 DateTime2 也为 null,则得到 DateTime3.
取值后,我需要比较一下,看是否少于2小时,然后再放入临时table。
示例,如果当前时间是下午 2 点 = 1400 小时
我要显示的最终输出
数据1 | 日期时间1 | 日期时间2 | 日期时间3 |
---|---|---|---|
第一个 | 2020-08-24 14:00:00.000 | 2020-08-24 14:30:00.000 | 2020-08-24 15:30:00.000 |
第二 | 空 | 2020-08-24 13:00:00.000 | 2020-08-24 14:30:00.000 |
听起来您想 select 在过去两个小时内具有日期时间字段的行。您不能使用像 COALESCE
这样的函数,因为那样会阻止使用任何覆盖列的索引。如果您使用例如:
WHERE COALESCE(DateTime1,DateTime2,DateTime3) >DATEADD(HOUR,-2,GETDATE())
服务器将无法使用任何覆盖日期字段的索引,并且将被迫扫描整个 table 以评估函数输出和过滤条件
一个简单的 WHERE
应该可以工作,甚至不检查 NULL
,因为与 NULL
的任何比较都失败了:
declare @cutoff datetime=DATEADD(HOUR,-2,GETDATE())
SELECT .....
WHERE
DateTime1 > @cutoff
OR DateTime2 > @cutoff
OR DateTime3 > @cutoff
如果您只想比较 time 部分,唯一有效的方法是使用 time
类型将时间部分提取到单独的字段中并对其进行索引.使用 提取时间部分,例如 cast(DateTime1 as time)
将阻止使用索引。
以下条件将通过扫描整个 table 来工作:
declare @cutoff time=cast(DATEADD(HOUR,-2,GETDATE()) as time);
SELECT ...
WHERE cast(COALESCE(DateTime1,DateTime2,DateTime3) as time) > @cutoff