问题描述
|
我的数据库表包含以下列:
A1,A2,A3,A4,A5,A6
每当遇到空列时,我都必须更新这些记录并向左移动值。目的是在具有从左开始的值的列之间不具有空值。例如,如果:
A1 = NULL,A2 = 1,A3 = 4,A4 = 5,A5 = 9,A6 = 8
我必须将值向左移动,结果将是:
A1 = 1,A2 = 4,A3 = 5,A4 = 9,A5 = 8,A6 = NULL
到目前为止,我已经提出了以下查询,但是它很慢。让我知道您是否可以调整查询以使其更快。还有一件事,如果我在C#中执行此操作怎么办?如果我遍历数据行并更新每一行,速度会更快吗?
UPDATE myTable SET
A5 = A6,A6 = NULL
WHERE (A5 IS NULL) AND (NOT A6 IS NULL)
UPDATE myTable SET
A4 = A5,A5 = A6
WHERE (A4 IS NULL) AND (NOT A5 IS NULL)
UPDATE myTable SET
A3 = A4,A4 = A5,A5 = A6
WHERE (A3 IS NULL) AND (NOT A4 IS NULL)
UPDATE myTable SET
A2 = A3,A3 = A4,A5 = A6
WHERE (A2 IS NULL) AND (NOT A3 IS NULL)
UPDATE myTable SET
A1 = A2,A2 = A3,A5 = A6
WHERE (A1 IS NULL) AND (NOT A2 IS NULL)
解决方法
鉴于
[anything] + NULL + [anything]
为零,那怎么办?
declare @t table(A1 int,A2 int,A3 int,A4 int,A5 int,A6 int)
insert @t values
(NULL,2,3,4,5,6),(1,NULL,NULL),6)
update @t
set A1 = coalesce(A1,A2),A2 = case when A1 + A2 is null then A3 else A2 end,A3 = case when A1 + A2 + A3 is null then A4 else A3 end,A4 = case when A1 + A2 + A3 + A4 is null then A5 else A4 end,A5 = case when A1 + A2 + A3 + A4 + A5 is null then A6 else A5 end,A6 = case when A1 + A2 + A3 + A4 + A5 is null then null else A6 end
from @t
select * from @t
A1 A2 A3 A4 A5 A6
2 3 4 5 6 NULL
1 3 4 5 6 NULL
1 2 4 5 6 NULL
1 2 3 5 6 NULL
1 2 3 4 6 NULL
1 2 3 4 5 NULL
1 2 3 4 5 6
, 在这样的语句中如何使用合并:
update mytable
set a1 = coalesce(a1,a2,a3,a4,a5,a6),a2=coalesce(a2,a3=coalesce(a3,a4=coalesce(a4,a5=coalesce(a5,a6)
, 如果您无法控制代码或数据库设计,建议使用触发器来解决此问题。
设置INSERT,UPDATE触发器,该触发器将专门仅查看刚刚更改的行。这样,您就不会对已经检查一致性的数据运行更新语句。要检查/更新的行越少,意味着性能越高。
您可以通过查看虚拟inserted
和deleted
表将其范围缩小至已触及的行。
触发器到位后,请触摸所有现有行(以在上面触发触发器),或运行原始脚本以确保所有行均处于一致状态。
, 如果不是那样,您是否尝试过在所有列上添加覆盖索引?尝试通过以下方式添加索引。这样一来,它就可以找到需要更快更新的行,而覆盖索引是这样,因此它不必进行书签查找即可获取所需的下一个值。
A1,A2,A3,A4,A5,A6
A2,A6
A3,A6
A4,A6
A5,A6