mysql - 在(Mysql?)中存储不重叠日期范围的最佳方法是什么?

标签 mysql sql

我正在构建一个管理学生和类(class)的系统。学生可以更换类(class),但在同一天不能被分配到多个类(class)。我正在重新考虑我的实现方式。

显而易见的方法是拥有 attendance_periods表,其中包含列 student_id , class_id , fromto 。但是,这可能会存储无效数据。例如,学生 A 在 2021-08-01 至 2021-09-01 期间在 A 类,在 2021-08-15 至 2021-09-15 期间在 B 类。至少,据我所知,在数据库层面没有办法杜绝此类情况的发生。

为了防止这种重叠发生,我让表格只有 student_id , class_idfrom ,与 student_id 对和from独特且class_id可以为空。该行不是“说”学生从日期 A 到日期 B 在 X 类,而是仅说明学生加入类(class)或离开学校的时间(如果他们未分配到任何类(class))。

但是,这使得一些查询变得非常困难。例如,要获取特定日期哪个类(class)的学生,这是我一直在使用的查询:

select
  `class_attendance_periods`.*
from
  `class_attendance_periods`
  left join (
    select
      `id` as `later_id`,
      `student_id` as `later_student_id`,
      `class_id` as `later_class_id`,
      `from` as `later_from`
    from
      `class_attendance_periods`
    where
      `from` <= '2021-08-30'
  ) as `later` on `class_attendance_periods`.`student_id` = `later`.`later_student_id`
  and `class_attendance_periods`.`from` < `later`.`later_from`
where
  `later`.`later_from` is null
  and `class_attendance_periods`.`from` <= '2021-08-30'

但是,我现在要做的工作,需要把每个类(class)的学生都取一段时间。这当然是我可以在服务器的 PHP 端工作的东西,但我不知道如何将查询限制为适用的行。例如,WHERE from <= last_day_of_the_interval条件阻止获取我不需要的 future 出勤期,但我不知道如何不获取过去不需要的行。另外,如果可能的话,我希望数据库能够承担繁重的工作。

所以我的问题是双重的:

1- 有没有更好的方法来实现这种情况?我感兴趣的是让数据库不允许无效数据,同时可以轻松查询给定日期的类(class)学生或给定时间段的所有类(class)学生。

2-如果这个结构还不错,有没有办法让查询动态计算出勤期的结束时间(即“截止”日期)?比如添加 next attendance period's 'from' minus one day柱子。这样查询会更容易进行。

最佳答案

However, this has been making some queries very difficult. For example, to get what students are on which class on a given day

WITH
cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY student_id ORDER BY `from` DESC) rn
    FROM class_attendance_periods
    WHERE `from` <= '2021-08-30'
)
SELECT *
FROM cte
WHERE rn = 1;

需要 MySQL 版本 8+。

关于mysql - 在(Mysql?)中存储不重叠日期范围的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68984779/

相关文章:

sql - 如何与另一个表并排显示外键?

java - 如何在 JDBC PreparedStatement 中设置公式

mysql - 如何使用 DBAL 查询构建器来构建这个子查询?

php - 查询 : Find string in database field

mysql - 在 RoR 模式中添加主键约束

sql - 错误itgensql005 : unknown identifier 'ID'

c++ - soci按行打印出表格中的所有数据

mysql - 如何替换 MySQL 中的 HTML 行?

javascript - 未捕获的 ReferenceError PouchDB

sql - 查询以计算演出收入占所有演出总收入的比例