【问题标题】:Limit same rows in junction table限制联结表中的相同行
【发布时间】:2016-05-17 20:23:16
【问题描述】:

我有一个表(oracle 数据库),用于存储部门及其员工。

表:部门员工

╔══════════════╦═══════════╦═════════════╦═══════════════════════════╗
║    Column    ║ Data type ║ Nullability ║        Description        ║
╠══════════════╬═══════════╬═════════════╬═══════════════════════════╣
║ DepartmentID ║ INT       ║ NOT NULL    ║ Foreign Key to Department ║
║ EmployeeID   ║ INT       ║ NOT NULL    ║ Foreign Key to Employee   ║
║ StartDate    ║ DATE      ║ NOT NULL    ║ Date the employee joined  ║
║ EndDate      ║ DATE      ║ NULL        ║ Date the employee left    ║
╚══════════════╩═══════════╩═════════════╩═══════════════════════════╝

员工应该只有一 (1) 个他目前工作的部门。 他工作的部门没有 EndDate (= NULL)。

所以查询将是:

选择 * FROM部门员工 WHERE EmployeeID = 1 AND EndDate 为空;

当员工不再在公司工作时,他将没有 (0) 个具有 EndDate 的部门。

所以我的问题是: 如何确保表中只有 1 行或 0 行的 EmployeeID 的 EndDate 设置为 NULL? 谢谢。

【问题讨论】:

  • 就像一个想法..您可以添加一个coulum来指定员工是否正在工作。 Active = Y/N
  • 只需在该 UNIQUE(employeeID,EndDate) 上放置一个唯一索引。顺便说一句,更合适的方法是使用开放式结束日期,例如 - 31/12/2999。
  • @Moudiz 该列已经在 Employee 表中
  • @sagi 唯一索引听起来像是要走的路。我不喜欢使用开放式结束日期(例如,您想计算某人在部门工作的天数)
  • 所以你不使用 end_date,你使用当前日期或其他日期。一个空值将如何帮助您比现在很远的开放日期更好?不应使用 Null 值,因为它可能会在以后导致错误。

标签: sql oracle


【解决方案1】:

您可以添加唯一索引,确保每个employeedId 和endDate 最多有一条记录:

create unique index EmployeeEndDate on DepartmentEmployee
(
     employeeId,
     endDate
);

【讨论】:

    【解决方案2】:

    这是一种选择:在没有结束日期的记录上创建唯一索引。那是一个包含 CASE WHEN 的功能索引。

    create unique index idx_OnlyOneNoEndDate on DepartmentEmployee
    (
      case when EndDate is null then EmployeeID end
    );
    

    当 EndDate 被填充时,两个表达式都为空,并且默认情况下 Oracle 不会在空值上创建索引条目,因此不会写入任何条目。但是,如果 EndDate 为空,则我们为 EmployeeID 编写一个条目。当 EndDate 为 NULL 的员工的第二条记录被插入时,索引的唯一性就会消失,我们会得到一个异常。

    这也意味着您必须首先为现有记录编写 EndDate,然后然后插入新记录。如果你反之亦然,你会得到例外。如果这对您来说是个问题,那么您应该能够通过在 case when EndDate is null then EmployeeID end 上创建一个虚拟列并在此列上创建一个 可延迟 唯一索引来规避这个问题。 (可延迟索引只能引用列。很遗憾,它们不能是功能索引。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-18
      • 2017-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-04
      • 1970-01-01
      相关资源
      最近更新 更多