- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我检查了几个关于这个主题的旧问题,例如:Calendar Recurring/Repeating Events - Best Storage Method然而,答案在性能方面非常糟糕并且在实现中很麻烦。从另一个答案中,很容易看出为什么接受的答案是一个坏主意:一个月的事件需要 90 个查询。这是 Not Acceptable 。
无论如何,这是我面临的问题,因此您不必重新阅读这些问题:
如果有任何帮助,我将不胜感激!我阅读了几篇关于该主题的论文,但仍然找不到我可以专门在 SQL 中使用的内容。
最佳答案
我想出的解决方案是我有一个事件表,其中有五个定义事件重复发生的字段,定义如下。然后我还有一个时间表,我用事件的实际发生填充了它。我确实需要一个结束日期,即使他们指定了几年后的事件,它也是每月一次的事件,不会在日程表中创建那么多条目。
因此,事件存储在事件表中,如果没有重复发生,则事件表中包含描述事件整个持续时间的 startDateTime 和 endDateTime。这两个日期时间字段还定义事件的整体开始和结束(如果它是重复事件)。在同一个事件表中,我们有五个定义重复的字段,如下所示。
Schedule 表存储每个事件的单独发生。所以它有一个 eventId、startDateTime 和 endDateTime。此开始和结束仅指每次出现,而不是整个跨度。
为了查询一段时间内发生的所有预定事件,我只查询调度表以检查是否有任何匹配此条件的事件:
select * from schedule where schedule.startDateTime < @queryPeriodEnd and schedule.endDateTime > @queryPeriodStart
此查询仅向我提供部分或全部发生在我的查询期间内的计划条目。要获取事件数据,只需加入事件表即可。
有趣的部分是计算每月的第二个星期四。这发生在用于确定给定事件的所有计划发生的实际代码中。我还在下面附上了我的代码。
事件重复字段
反复出现0=没有复发1=每天2=每周3=每月
递归间隔这是重复之间的周期数。如果事件每 5 天重复一次,recurs_interval 的值为 5,recurs 的值为 1。如果事件每 3 周重复一次,recurs_interval 的值为 3,recurs 的值为 2。
重复日如果用户选择每月类型重复,则在一个月的给定日期(例如:10 号或 14 号)。这有那个日期。如果用户没有选择每月或每月的特定日期重复,则该值为 0。否则该值为 1 到 31。
递归序数如果用户选择了每月类型的重复,但是一天的顺序类型(例如:第一个星期一、第二个星期四、最后一个星期五)。这将具有该序号。如果用户没有选择这种类型的重复,则该值为 0。1=第一2=秒3=第三4=第四5=最后
recurs_weekdays对于每周和每月的顺序重复,这将存储重复发生的工作日。 1=星期日2=星期一4=星期二8=星期三16=星期四32=星期五64=星期六
所以,每 4 周的周六和周日就是recurs=2, recurs_interval=4, recurs_weekdays=65 (64 + 1)同样,每三个月的第一个星期五是recurs=3, recurs_interval=3, recurs_ordinal=1, recurs_weekdays=32
代码
thisEvent.occurrences = new List<ScheduleInstance>();
DateTime currentDateTime = (DateTime) thisEvent.start;
DateTime currentEndTime;
BitArray WeekDayRecurrenceBits = new BitArray(new Byte[] {(Byte) thisEvent.recursWeekdays});
while (currentDateTime < thisEvent.end)
{
currentEndTime = new DateTime(currentDateTime.Year, currentDateTime.Month, currentDateTime.Day,
thisEvent.end.Value.Hour, thisEvent.end.Value.Minute, thisEvent.end.Value.Second);
switch (thisEvent.recurs)
{
case (RecurrenceTypeEnum.None):
AddOccurrenceToRooms(thisEvent, currentDateTime, currentEndTime);
currentDateTime = (DateTime)thisEvent.end;
break;
case (RecurrenceTypeEnum.Daily):
AddOccurrenceToRooms(thisEvent, currentDateTime, currentEndTime);
currentDateTime = currentDateTime.AddDays(thisEvent.recursInterval);
break;
case (RecurrenceTypeEnum.Weekly):
int indexIntoCurrentWeek = (int) currentDateTime.DayOfWeek;
while ((indexIntoCurrentWeek < 7) && (currentDateTime < thisEvent.end))
{
if (WeekDayRecurrenceBits[(int) currentDateTime.DayOfWeek])
{
AddOccurrenceToRooms(thisEvent, currentDateTime, currentEndTime);
}
currentDateTime = currentDateTime.AddDays(1);
currentEndTime = currentEndTime.AddDays(1);
indexIntoCurrentWeek++;
}
currentDateTime = currentDateTime.AddDays(7 * (thisEvent.recursInterval - 1));
break;
case (RecurrenceTypeEnum.Monthly):
if (thisEvent.recursDay == 0)
{
DateTime FirstOfTheMonth = new DateTime(currentDateTime.Year, currentDateTime.Month, 1);
int daysToScheduleOccurrence = ((thisEvent.recursWeekdays - (int)FirstOfTheMonth.DayOfWeek + 7) % 7)
+ ((thisEvent.recursOrdinal - 1) * 7)
- currentDateTime.Day + 1;
if (daysToScheduleOccurrence >= 0)
{
currentDateTime = currentDateTime.AddDays(daysToScheduleOccurrence);
currentEndTime = currentEndTime.AddDays(daysToScheduleOccurrence);
if (currentDateTime < thisEvent.end)
{
AddOccurrenceToRooms(thisEvent, currentDateTime, currentEndTime);
}
}
}
else
{
if (currentDateTime.Day <= thisEvent.recursDay && thisEvent.recursDay <= DateTime.DaysInMonth(currentDateTime.Year, currentDateTime.Month) )
{
currentDateTime = currentDateTime.AddDays(thisEvent.recursDay - currentDateTime.Day);
currentEndTime = currentEndTime.AddDays(thisEvent.recursDay - currentEndTime.Day);
AddOccurrenceToRooms(thisEvent, currentDateTime, currentEndTime);
}
}
currentDateTime = currentDateTime.AddDays((currentDateTime.Day - 1) * -1).AddMonths(thisEvent.recursInterval);
break;
default:
break;
}
}
关于mysql - 如何创建一个包含可以轻松查询的重复事件的 SQL 日历?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31392033/
SQL、PL-SQL 和 T-SQL 之间有什么区别? 谁能解释一下这三者之间的区别,并提供每一个的相关使用场景? 最佳答案 SQL 是一种对集合进行操作的查询语言。 它或多或少是标准化的,几乎所有关
这个问题已经有答案了: What is the difference between SQL, PL-SQL and T-SQL? (6 个回答) 已关闭 9 年前。 我对 SQL 的了解足以完成我的
我在数据库中有一个 USER 表。该表有一个 RegistrationDate 列,该列有一个默认约束为 GETDATE()。 使用 LINQ 时,我没有为 RegistrationDate 列提供任
我有一个可能属于以下类型的字符串 string expected result 15-th-rp 15 15/12-rp 12 15-12-th
很难说出这里问的是什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或言辞激烈,无法以目前的形式合理回答。如需帮助澄清此问题以便可以重新打开,visit the help center . 9年前关闭
我有一个存储过程(称为 sprocGetArticles),它从文章表中返回文章列表。这个存储过程没有任何参数。 用户可以对每篇文章发表评论,我将这些评论存储在由文章 ID 链接的评论表中。 有什么方
我目前正在做一个 *cough*Oracle*cough* 数据库主题。讲师介绍embedded SQL作为让其他语言(例如 C、C++)与(Oracle)数据库交互的方式。 我自己做了一些数据库工作
SQL Server 中 SQL 语句的最大长度是多少?这个长度是否取决于 SQL Server 的版本? 例如,在 DECLARE @SQLStatement NVARCHAR(MAX) = N'S
这个问题已经有答案了: Simple way to transpose columns and rows in SQL? (9 个回答) 已关闭 8 年前。 CallType
预先感谢您对此提供的任何帮助。 假设我有一个查询,可以比较跨年的数据,从某个任意年份开始,永无止境(进入 future ),每年同一时期直到最后一个完整的月份(其特点是一月数据永远不会显示至 2 月
我在数据库中有一个 USER 表。该表有一个 RegistrationDate 列,该列的默认约束为 GETDATE()。 使用 LINQ 时,我没有为 RegistrationDate 列提供任何数
下面是我试图用来检查存储过程是否不存在然后创建过程的 sql。它会抛出一个错误:Incorrect syntax near the keyword 'PROCEDURE' IF NOT EXISTS
我有一个同事声称动态 SQL 在许多情况下比静态 SQL 执行得更快,所以我经常看到 DSQL 到处都是。除了明显的缺点,比如在运行之前无法检测到错误并且更难阅读,这是否准确?当我问他为什么一直使用
来自 lobodava 的动态 SQL 查询是: declare @sql nvarchar(4000) = N';with cteColumnts (ORDINAL_POSITION, CO
使用 SQL Server 中的存储过程执行动态 SQL 命令的现实优点和缺点是什么 EXEC (@SQL) 对比 EXEC SP_EXECUTESQL @SQL ? 最佳答案 sp_executes
我有这个有效的 SQL 查询: select sum(dbos.Points) as Points, dboseasons.Year from dbo.StatLines dbos i
我正在调试一些构建成功运行的 SQL 命令的代码。 然而,在查询结束时,查询结果似乎被写入了一个文本文件。 完整的查询如下 echo SELECT DATE,DATETABLE,DATE,APPDAT
我有一些创建表的 .sql 文件(MS SQL 数据库): 表_1.sql: IF OBJECT_ID (N'my_schema.table1', N'U') IS NOT NULL DROP TAB
我写了下面的 SQL 存储过程,它一直给我错误@pid = SELECT MAX(... 整个过程是: Alter PROCEDURE insert_partyco @pname varchar(20
我在 SQL Server 2005 中有包含两列 Fruit 和 Color 的表,如下所示 Fruit Colour Apple Red Orange
我是一名优秀的程序员,十分优秀!