SQL 查询更新 table 具有时间依赖性

SQL Query to update table with time dependencies

我正在为我的应用程序运行带有 VBA 界面的 WAMP 设置。此应用程序通过基于时间的关系定义 "employees" 及其与 "organisation" 的关系。


我在想出一种有效的方法来更新数据库中的 table 时遇到了麻烦。有 3 个 table 定义:员工、组织和员工之间的关系以及雇佣的开始/结束日期 organisation.The 当需要拆分跨越一个时期的条目时,就会出现问题:即,最初定义员工在组织工作 1 年的条目被拆分为员工在今年内为另一家企业工作 1 个月。

我在以下庄园中构建了我的 table:

tbl_employee

+----+-----------+----------+
| id | firstname | lastname |
+----+-----------+----------+
|  1 | jordan    | bean     |
|  2 | kevin     | sams     |
+----+-----------+----------+

tbl_organisation

+----+----------+
| id |   name   |
+----+----------+
|  1 | nanosoft |
|  2 | attic Gm |
+----+----------+

tbl_relation_employee_organisation

+----+-------------+-----------------+------------+------------+
| id | employee_id | organisation_id | validfrom  |  validto   |
+----+-------------+-----------------+------------+------------+
|  1 |           1 |               1 | 2015-01-01 | 2016-01-01 |
+----+-------------+-----------------+------------+------------+


现在我面临的问题是更新 tbl_relation_employee_organisation table 以便员工可以在现有的 extry 之间更改组织,即如果员工 1 与来自 [ 的组织 2 相关=21=]2015-10-012015-11-01

(也许我的问题需要修改我的 table 结构:将员工与组织联系起来,只有更改发生的日期?)


我可以在此结构上运行什么查询以 'split' 关系 table 上的行按以下方式

+----+-------------+-----------------+------------+------------+
| id | employee_id | organisation_id | validfrom  |  validto   |
+----+-------------+-----------------+------------+------------+
|  1 |           1 |               1 | 2015-01-01 | 2015-09-30 |
|  2 |           1 |               2 | 2015-10-01 | 2016-11-01 |
|  3 |           1 |               1 | 2015-11-02 | 2016-01-01 |
+----+-------------+-----------------+------------+------------+

Q: 我可以用什么查询运行 这个结构到 'split' 关系 table.[=23= 上的行]

A: 根据提供的信息,'split' 需要 两个 查询、现有行的更新,以及一个 INSERT 添加两个新行。例如:

UPDATE tbl_relation_employee_organisation t 
   SET t.validto = '2015-09-30'
 WHERE t.id = 1

INSERT INTO tbl_relation_employee_organization 
(id, employee_id, organisation_id, validfrom, validto)
VALUES (2, 1, 2, '2015-10-01','2015-11-01')
     , (3, 1, 1, '2015-11-02','2016-01-01')

这对 'split' 行来说是最有效的(就数据库性能而言)。


跟进

要在单个语句中执行此操作,如果 id 列上有 UNIQUE(或 PRIMARY KEY)约束...

INSERT INTO tbl_relation_employee_organization 
(id, employee_id, organisation_id, validfrom, validto)
VALUES (1, 1, 1, '2015-01-01','2015-09-30')
     , (2, 1, 2, '2015-10-01','2015-11-01')
     , (3, 1, 1, '2015-11-02','2016-01-01')
ON DUPLICATE KEY
UPDATE employee_id     = VALUES(employee_id)
     , organisation_id = VALUES(organisation_id)
     , validfrom       = VALUES(validfrom)
     , validto         = VALUES(validto)

请注意,您至少需要提供要更新的行的 id 值;如果 idAUTO_INCREMENT,您可以用 NULL 代替第二行和第三行的 id 值。

或者,如果您对 (employee_id,validfrom) 有 UNIQUE 约束,您可以省略 id 值,并允许由这两列的值引发 DUPLICATE KEY 异常,并得到执行更新操作,无需提供 id 值。 (使用这种方法,尝试 INSERT 重复行将用完一个 auto_increment 值;即使未插入行,该值也会被消耗,因为 MySQL执行操作(在尝试插入之前不会抛出 DUPLICATE KEY 异常,并且在尝试执行插入时 auto_increment 值为 retrieved/incremented。)