Sql 限制联接表中的相同行

Sql 限制联接表中的相同行,sql,oracle,Sql,Oracle,我有一个表(oracle数据库),用于存储部门及其员工 表:部门员工 ╔══════════════╦═══════════╦═════════════╦═══════════════════════════╗ ║ Column ║ Data type ║ Nullability ║ Description ║ ╠══════════════╬═══════════╬═════════════╬═══════════════════════════╣ ║

我有一个表(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)个目前工作的部门。 他正在工作的部门没有结束日期(=NULL)

因此,问题是:

挑选* 来自部门员工 其中EmployeeID=1 并且EndDate为空

当员工不再在公司工作时,他将没有(0)个具有结束日期的部门

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

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

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

这里有一个选项:在没有结束日期的记录上创建一个唯一的索引。这是一个包含CASE WHEN的函数索引

create unique index idx_OnlyOneNoEndDate on DepartmentEmployee
(
  case when EndDate is null then EmployeeID end
);
当EndDate被填充时,两个表达式都为null,Oracle默认情况下不会在null值上创建索引项,因此不会写入任何项。如果EndDate为空,那么我们为EmployeeID写一个条目。当插入EndDate为NULL的员工的第二条记录时,索引的唯一性被破坏,我们得到一个异常


这也意味着您必须先为现有记录写入结束日期,然后再插入新记录。如果你做了,反之亦然,你会得到例外。如果这对您来说是一个问题,那么您应该能够通过在
案例中创建一个虚拟列来规避此问题,当EndDate为null时,则改为EmployeeID end
,并在此列上创建一个可延迟的唯一索引。(可延迟索引必须仅引用列。很遗憾,它们不能是功能索引。)

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