我有一个典型的非标准化表(tempTable
)具有多个编号的列(rep1
,rep2
,...)。
所以我编写了一个脚本将非标准化数据插入到标准化表中(myTable
):
insert into myTable
select idRep,rep FROM
(
select idRep, ISNULL(rep1,'') as rep FROM tempTable
union
select idRep, ISNULL(rep2,'') as rep FROM tempTable
union
select idRep, ISNULL(rep3,'') as rep FROM tempTable
union
select idRep, ISNULL(rep4,'') as rep FROM tempTable
union
select idRep, ISNULL(rep5,'') as rep FROM tempTable
) as t
注:表myTable
还包含一个自动递增的IDENTITY
列作为其PRIMARY KEY
.
在我的场景中,rep1、rep2、rep3、rep4、rep5 的顺序很重要。奇怪的是,当我执行脚本时,数据没有按正确的顺序插入,例如自动生成的 id '1000' 具有来自 'rep3' 的值,而 id '1001' 具有来自 'rep1' 的值。
这是为什么?脚本是如何执行的?
使用 UNION 时它没有按照您期望的顺序进行的原因是 union 试图强加唯一性,因此它会一起处理所有这些行并按照对引擎最方便的顺序将它们取出。
如果您按照 Parado 的建议切换到 UNION ALL (它不会尝试强加唯一性),它将不会进行处理,它们将按照您放入的顺序进入表中,almost每时每刻。然而,这并不能得到保证,并且其他进程中发生的某些非常不寻常的情况(尤其是那些以某种方式触及临时表的进程)可能会影响它。
如果您按照 Kash 建议使用 order by,那么这将保证 id 的顺序(这可能很重要),但从技术上讲,不会保证行插入的顺序(这在实践中很少重要)。
关于其中的一些内容有很好的总结MSDN http://blogs.msdn.com/b/sqltips/archive/2005/07/20/441053.aspx.
所以,这就解决了原因。至于如何获得你真正想要的东西,我会使用 Kash 的建议,即添加一个列以与 order by 子句一起使用,但我会使用 UNION ALL 而不是 UNION。使用 UNION 就像添加和隐式“不同”要求,它会占用处理器周期并使查询计划更加复杂。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)