使用UNION INSERT INTO SELECT奇怪的顺序

Fra*_*s P 3 t-sql sql-server union sql-server-2008

我有一个典型的非标准化表(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
Run Code Online (Sandbox Code Playgroud)

注意:该表myTable还包含一个自动递增的IDENTITYPRIMARY KEY.

订单rep1,rep2,rep3,rep4,rep5在我的场景中非常重要.奇怪的是,当我执行脚本时,数据没有以正确的顺序插入,例如自动生成的id'1000'具有来自'rep3'的值,而id'1001'具有来自'rep1'的值.

这是为什么?脚本是如何执行的?

Tim*_*man 8

它在使用UNION时没有按照你期望的顺序进行的原因是union试图强加uniquness,因此它将所有这些行一起处理并按照最方便引擎的顺序将它们引出.

如果切换到UNION ALL(不试图强加唯一性),因为Parado建议它不会进行处理,并且它们将按照您放入的顺序进入表中,几乎所有时间.然而,这并不是很好的,并且在其他过程中发生的某些非常特殊的情况(特别是那些以某种方式触及你的tempTable)可能会影响它.

如果按照Kash的建议使用订单,那么这将获得id的顺序(这可能很重要),但技术上并不是行插入的顺序(在实践中这很少很重要).

MSDN上有一些很好的总结.

所以,这就解决了原因.至于如何获得你真正想要的东西,我会使用Kash的建议添加一个用于order by子句的列,但我会使用UNION ALL而不是UNION.使用UNION就像添加和隐含的"不同"要求一样,这会占用处理器周期并使查询计划更加复杂.