我想通过最接近的时差来获取记录顺序。
我已经计算了order by子句中的时差,这会导致性能问题,因为表有大约2M条记录。
注意:在我的实际查询中,没有连接,表只有13列。
获取此样本数据:
CREATE TABLE yourtable
([ID] int, [User] varchar(5), [ScheduleOn] datetime)
;
INSERT INTO yourtable
([ID], [User], [ScheduleOn])
VALUES
(1, 'User1', '2018-01-09 11:50:03.103'),
(2, 'User2', '2018-01-09 11:38:03.103'),
(3, 'User3', '2018-01-09 11:42:03.103'),
(4, 'User4', '2018-01-09 11:45:03.103'),
(5, 'User5', '2018-01-09 11:43:03.103'),
(6, 'User6', '2018-01-09 11:44:03.103'),
(7, 'User7', '2018-01-09 11:40:03.103')
;
这是我的示例查询。
ScheduleOn是日期时间的类型。
Declare @currentDate datetime = '2018-01-09 11:42:03.103'
select *, ABS(datediff(mi,@currentDate,ScheduleOn)) AS JustToSee from yourtable
order by ABS(datediff(mi,@currentDate,ScheduleOn))
我想知道,是否有其他人通过最接近的时差获得记录顺序。
答案 0 :(得分:2)
虽然您尚未回复评论中提出的问题,但我认为您或其他人可能会看到提及的查询类型。
给出的示例很昂贵,因为在ABS(DATEDIFF())
操作之后,数据被认为是乱序的。这意味着对数据进行排序会变得很昂贵(排序200万行)。
但是,只有那些最接近@currentDate值的行才有意义,在必须应用排序之前,可以限制样本大小。
WITH
closest_100_each_side
(
SELECT TOP(100) *, ScheduleOn - @currentDate AS diff FROM yourTable WHERE ScheduleOn >= @currentDate ORDER BY ScheduleOn ASC
UNION ALL
SELECT TOP(100) *, @currentDate - ScheduleOn AS diff FROM yourTable WHERE ScheduleOn < @currentDate ORDER BY ScheduleOn DESC
)
SELECT TOP(100)
*
FROM
closest_100_each_side
ORDER BY
diff ASC
在ScheduleOn
上使用适当的索引时,CTE中的两个查询变得微不足道,最后的查询现在只需要对200行进行排序以找到最接近的100行。
比将TOP(100)
简单地应用到现有查询更快。
因此,理解数据的用途以及在执行查询后如何实际使用它变得非常重要。这一小段信息可能允许对查询进行微小更改,以显着提高性能。
答案 1 :(得分:0)
只要MS SQL DATETIME
在内部是2个整数,你就可以这样做:
Declare @currentDate datetime = '2018-01-09 11:42:03.103'
Declare @currentDateFloat float = CONVERT(float, @currentDate)
select *, ABS(Cast((@currentDateFloat - ScheduleOn) as Float)) AS JustToSee
from yourtable
order by ABS(Cast((@currentDateFloat - ScheduleOn) as Float))
但我怀疑它会更快,因为我已经检查了实际的执行计划,它与您的查询相同。
答案 2 :(得分:-1)
不确定,但你可以试试这个:
WITH CTE AS (
select *, ABS(datediff(mi,@currentDate,ScheduleOn)) AS JustToSee from
yourtable )
SELECT * FROM CTE ORDER BY JustToSee