标准化 SQL table - 将 1 行转换为 6 行
Normalize a SQL table - convert 1 row to 6 rows
我有一个 table,其中填充了来自需要规范化的制造系统的数据。此阶段 table 有一个关键字段 - LOTCODE - 加上 6 个 PARTSTATUS 字段,PART1、PART2 等的状态代码 (INT)
每个小时我都想查询暂存 table,对于找到的每一行,将 6 行插入到存档 table 中,该存档将包含关键字段 LOTCODE 和 PARTLOCATION 以及第三个字段 PARTSTATUS。将数据插入存档 table 后,暂存 table 中的行将被删除。
有没有办法只用查询来做到这一点,或者我是否需要逐行遍历暂存 table,在存档 table 中插入 6 行,然后删除原始行?
数据库是 MS SQL 2016。制造系统每小时将大约 1440 行添加到暂存 table。
暂存 table 示例行:
Lot, Part1Status, Part2Status, Part3Status, Part4Status, Part5Status, Part6Status
ABCDE, 1010, 1010, -50, 1010, 990, 1010
存档table样本数据
Lot, PartLocation, Stats
ABCDE, 1, 1010
ABCDE, 2, 1010
ABCDE, 3, -50
ABCDE, 4, 1010
ABCDE, 5, 990
ABCDE, 6, 1010
这是一个 TRY/CATCH
脚本,它在显式事务中执行 INSERT
和 DELETE
语句,其中 XACT_ABORT
已设置为 ON
以确保在抛出异常的情况下完全回滚两个 DML 语句。像这样
set nocount on;
set xact_abort on;
begin transaction
begin try
declare @lc table(LOTCODE int unique not null);
insert ArchiveTable(Lot, PartLocation, [Stats])
output inserted.LOTCODE into @lc
select LOTCODE, v.(
from StagingTable st
cross apply (values (1, st.Part1Status),
(2, st.Part2Status),
(3, st.Part3Status),
(4, st.Part4Status),
(5, st.Part5Status),
(6, st.Part6Status)) v(PARTLOCATION, [STATS]);
delete st
from StagingTable st
join @lc lc on st.LOTCODE=lc.LOTCODE;
commit transaction;
end try
begin catch
/* throw / raiserror / logging */
rollback transaction;
end catch
我有一个 table,其中填充了来自需要规范化的制造系统的数据。此阶段 table 有一个关键字段 - LOTCODE - 加上 6 个 PARTSTATUS 字段,PART1、PART2 等的状态代码 (INT)
每个小时我都想查询暂存 table,对于找到的每一行,将 6 行插入到存档 table 中,该存档将包含关键字段 LOTCODE 和 PARTLOCATION 以及第三个字段 PARTSTATUS。将数据插入存档 table 后,暂存 table 中的行将被删除。
有没有办法只用查询来做到这一点,或者我是否需要逐行遍历暂存 table,在存档 table 中插入 6 行,然后删除原始行?
数据库是 MS SQL 2016。制造系统每小时将大约 1440 行添加到暂存 table。
暂存 table 示例行:
Lot, Part1Status, Part2Status, Part3Status, Part4Status, Part5Status, Part6Status
ABCDE, 1010, 1010, -50, 1010, 990, 1010
存档table样本数据
Lot, PartLocation, Stats
ABCDE, 1, 1010
ABCDE, 2, 1010
ABCDE, 3, -50
ABCDE, 4, 1010
ABCDE, 5, 990
ABCDE, 6, 1010
这是一个 TRY/CATCH
脚本,它在显式事务中执行 INSERT
和 DELETE
语句,其中 XACT_ABORT
已设置为 ON
以确保在抛出异常的情况下完全回滚两个 DML 语句。像这样
set nocount on;
set xact_abort on;
begin transaction
begin try
declare @lc table(LOTCODE int unique not null);
insert ArchiveTable(Lot, PartLocation, [Stats])
output inserted.LOTCODE into @lc
select LOTCODE, v.(
from StagingTable st
cross apply (values (1, st.Part1Status),
(2, st.Part2Status),
(3, st.Part3Status),
(4, st.Part4Status),
(5, st.Part5Status),
(6, st.Part6Status)) v(PARTLOCATION, [STATS]);
delete st
from StagingTable st
join @lc lc on st.LOTCODE=lc.LOTCODE;
commit transaction;
end try
begin catch
/* throw / raiserror / logging */
rollback transaction;
end catch