我有一个这样的表格方案:
CREATE TABLE MyEvents
(
Id INT PRIMARY KEY NOT NULL,
Name NVARCHAR(MAX) NOT NULL
);
CREATE TABLE MyEventSchedules
(
Id INT PRIMARY KEY NOT NULL,
MyEventId INT NOT NULL,
StartDate BIGINT NOT NULL,
TimeOfDay BIGINT NOT NULL,
Interval BIGINT NOT NULL
);
以及类似的数据:
INSERT INTO MyEvents (Id, Name)
VALUES (1, 'Event #1');
-- StartDate: new DateTime(2016, 5, 1), TimeOfDay: 16:00 - repeats every 3 day
INSERT INTO MyEventSchedules (Id, MyEventId, StartDate, TimeOfDay, Interval)
VALUES (1, 1, 635976576000000000, 576000000000, 2592000000000);
-- StartDate: new DateTime(2016, 5, 15), TimeOfDay: 12:00 - repeats every 30 day
INSERT INTO MyEventSchedules (Id, MyEventId, StartDate, TimeOfDay, Interval)
VALUES (2, 1, 635988672000000000, 432000000000, 25920000000000);
INSERT INTO MyEvents (Id, Name)
VALUES (2, 'Event #2');
-- StartDate: new DateTime(2016, 5, 2), TimeOfDay: 14:00 - repeats every day
INSERT INTO MyEventSchedules (Id, MyEventId, StartDate, TimeOfDay, Interval)
VALUES (3, 2, 635977440000000000, 504000000000, 864000000000);
INSERT INTO MyEvents (Id, Name)
VALUES (3, 'Event #3');
-- StartDate: new DateTime(2016, 5, 2), TimeOfDay: 22:00 - repeats every day
INSERT INTO MyEventSchedules (Id, MyEventId, StartDate, TimeOfDay, Interval)
VALUES (4, 3, 635977440000000000, 792000000000, 864000000000);
INSERT INTO MyEvents (Id, Name)
VALUES (4, 'Event #4');
-- StartDate: new DateTime(2016, 5, 2), TimeOfDay: 18:00 - repeats every day
INSERT INTO MyEventSchedules (Id, MyEventId, StartDate, TimeOfDay, Interval)
VALUES (5, 4, 635977440000000000, 648000000000, 864000000000);
BIGINT
用于将时间戳存储为数字(
https://msdn.microsoft.com/da-dk/library/system.datetime.ticks(v=vs.110).aspx
). 就像Unix时间戳一样。
我想
SELECT
最接近时间戳的事件,但我不知道怎么做。我想出了这个方法,但我不确定它是否正确。
你可以说,我想通过时间表找到下一个活动的时间
DECLARE @CurrentTime BIGINT = 635979600000000000; -- new DateTime(2016, 5, 4, 12, 0, 0).Ticks
SELECT *
FROM MyEvents
JOIN MyEventSchedules ON (MyEventSchedules.MyEventId = MyEvents.Id)
OUTER APPLY (
SELECT
((@CurrentTime - x.StartDate) / x.Interval) AS NumberOfTimesRepeated,
((((@CurrentTime - x.StartDate) / x.Interval) * x.Interval)) AS test,
(@CurrentTime - ((@CurrentTime - x.StartDate) / x.Interval)) Value
FROM MyEventSchedules x
WHERE x.MyEventId = MyEvents.Id) as Sort
ORDER BY Sort.Value
这里我有一些测试用例;
SELECT MyEvents.Id
FROM MyEvents
JOIN MyEventSchedules ON (MyEventSchedules.MyEventId = MyEvents.Id)
-- ORDER BY "closest to @CurrentTime"
-- Expected (1, 2, 4, 3)
DECLARE @CurrentTime BIGINT = 635978052000000000; -- new DateTime(2016, 5, 2, 17, 0 , 0).Ticks
SELECT MyEvents.Id
FROM MyEvents
JOIN MyEventSchedules ON (MyEventSchedules.MyEventId = MyEvents.Id)
-- ORDER BY "closest to @CurrentTime"
-- Expected (4, 3, 2, 1)
DECLARE @CurrentTime BIGINT = 635989068000000000; -- new DateTime(2016, 5, 15, 11, 0, 0).Ticks
SELECT MyEvents.Id
FROM MyEvents
JOIN MyEventSchedules ON (MyEventSchedules.MyEventId = MyEvents.Id)
-- ORDER BY "closest to @CurrentTime"
-- Expected (1, 2, 4, 3)