【发布时间】:2021-01-22 07:55:41
【问题描述】:
我需要从一个表中提取值并将其迁移到另一个表。源表包含特定生效日期的汇总值。如果值发生更改,如果组件值发生更改,并且数据从该生效日期开始有效,则会写入新行。
| source_id | entity_id | effective_date | component_1 | component_2 | component_3 |
|---|---|---|---|---|---|
| int(ai) | int | date | int | int | int |
| 1 | 159 | 2020-01-01 | 100 | 0 | 90 |
| 2 | 159 | 2020-05-01 | 140 | 50 | 90 |
| 3 | 159 | 2020-08-01 | 0 | 30 | 90 |
| 5 | 159 | 2020-12-01 | 0 | 30 | 50 |
我现在需要将此数据迁移到这样的新表中。目标是选择给定月份的数据,结果是给出该月的有效数据。
| id | source_id | entity_id | startdate | enddate | component_type | value |
|---|---|---|---|---|---|---|
| int(ai) | int | int | date | date | int | int |
每一行代表一个在一个月内有效的组件的值。 我现在通过将其设置为参数来运行每个有效月份的插入更新。 我将值更改作为新行插入到表中,并使用唯一键(实体 ID、有效日期、组件类型)防止重复
SET @effective_date = '2020-01-01';
INSERT INTO component_final
select NULL,
source_id,
entity_id,
effective_date,
NULL,
1,
component_1
FROM component_source
WHERE effective_date = @effective_date
AND component_1>0;
迁移第一行后应该是那个结果
| id | source_id | entity_id | startdate | enddate | component_type | value |
|---|---|---|---|---|---|---|
| 1 | 1 | 159 | 2020-01-01 | NULL | 1 | 100 |
| 2 | 1 | 159 | 2020-01-01 | NULL | 3 | 90 |
SET @effective_date = '2020-05-01';
INSERT INTO component_final
select NULL,
source_id,
entity_id,
effective_date,
NULL,
1,
component_1
FROM component_source
WHERE effective_date = @effective_date
AND component_1>0;
迁移第二行后应该是那个结果
| id | source_id | entity_id | startdate | enddate | component_type | value |
|---|---|---|---|---|---|---|
| 1 | 1 | 159 | 2020-01-01 | 2020-04-30 | 1 | 100 |
| 2 | 1 | 159 | 2020-01-01 | NULL | 3 | 90 |
| 3 | 2 | 159 | 2020-05-01 | NULL | 1 | 140 |
| 4 | 2 | 159 | 2020-05-01 | NULL | 2 | 50 |
因此,如果将来值发生变化,则必须设置结束日期。
如果将来更改组件,我将无法执行第二步,即更新数据。 也许可以在插入具有相同实体和组件的新行后将其作为触发器 - 但我无法使其工作。
一些想法?我只想在MySQL 内部处理这个问题。
【问题讨论】:
-
你的 MySQL 版本是多少?
-
您不能在一个查询中同时插入新行和更新现有行。在存储过程中执行您的操作。或者使用 2 个查询。
-
为什么要逐行迁移,而不是在一个查询中迁移整个数据数组?
-
@Akina 如果我知道该怎么做 - 我会的。上面的示例应该显示给出的内容和结果。
-
正如我在回答中指出的那样,我认为您可以通过删除
entity_id并仅考虑单个组件来进一步简化您的示例。
标签: mysql