我有一个表(oracle数据库),我存储部门及其员工。
表: DepartmentEmployee
╔══════════════╦═══════════╦═════════════╦═══════════════════════════╗
║ 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)。
所以查询将是:
SELECT * 来自DepartmentEmployee WHERE EmployeeID = 1 AND EndDate IS NULL;
如果员工不再在公司工作,他将没有(0)部门使用EndDate。
所以我的问题是: 如何确保表中只有1行或0行的EndDate为EmployeeID设置为NULL? 感谢。
答案 0 :(得分:1)
以下是一个选项:在没有结束日期的记录上创建唯一索引。这是一个包含CASE WHEN的功能索引。
create unique index idx_OnlyOneNoEndDate on DepartmentEmployee
(
case when EndDate is null then EmployeeID end
);
当EndDate被填充时,两个表达式都为空,并且Oracle默认情况下不会在空值上创建索引条目,因此不会写入任何条目。但是,如果EndDate为null,那么我们为EmployeeID编写一个条目。如果插入了EndDate NULL员工的第二条记录,那么索引的唯一性就会变得暴力,我们会得到例外。
这也意味着您必须首先为现有记录编写EndDate,然后然后插入新记录。如果你反之亦然,你会得到例外。如果这对您来说是个问题,那么您应该能够通过在case when EndDate is null then EmployeeID end
上创建虚拟列来绕过此问题,并在此列上创建可延迟的唯一索引。 (可延迟索引必须仅引用列。不幸的是,它们不能是功能索引。)
答案 1 :(得分:0)
您可以添加唯一索引,确保每个employeedId和endDate最多只有一条记录:
create unique index EmployeeEndDate on DepartmentEmployee
(
employeeId,
endDate
);