我正在使用SELECT
和UNION
批量插入表中。调用SELECT
时,我需要INSERT
值的顺序保持不变,但似乎这些值是以升序而不是我指定的顺序插入的。
例如,下面的插入语句
declare @QuestionOptionMapping table
(
[ID] [int] IDENTITY(1,1)
, [QuestionOptionID] int
, [RateCode] varchar(50)
)
insert into @QuestionOptionMapping (
RateCode
)
select
'PD0116'
union
select
'PL0090'
union
select
'PL0091'
union
select
'DD0026'
union
select
'DD0025'
SELECT * FROM @QuestionOptionMapping
将数据呈现为
(5 row(s) affected)
ID QuestionOptionID RateCode
----------- ---------------- --------------------------------------------------
1 NULL DD0025
2 NULL DD0026
3 NULL PD0116
4 NULL PL0090
5 NULL PL0091
(5 row(s) affected)
所选择的插入数据如何返回与插入时相同的顺序?
答案 0 :(得分:5)
SQL Server将您的行存储为无序集。数据点可以是连续的,也可以不是连续的,并且它们可以按照在插入语句中指定的数据的“顺序”,也可以不是。
查询数据时,引擎将按优化程序确定的最有效顺序检索行。不能保证每次查询数据时顺序都相同。
保证结果集顺序的唯一方法是在SELECT语句中包含一个显式的ORDER BY子句。
请参阅此答案,以更深入地讨论为何如此。 Default row order in SELECT query - SQL Server 2008 vs SQL 2012
通过对INSERT语句使用SELECT / UNION选项,可以创建SQL Server作为一组而不是一系列输入提取的无序集合。如果需要按顺序应用IDENTITY值,则将插入语句分成离散语句。更好的是,如果行编号很重要,请不要碰碰运气。明确编号插入行。
答案 1 :(得分:3)
SQL表确实表示无序集。但是,identity
上的insert
列将遵循order by
的顺序。
由于union
中的重复消除,您的数据混乱了。但是,我建议编写查询以对数据进行显式排序:
insert into @QuestionOptionMapping (RateCode)
select ratecode
from (values (1, 'PD0116'),
(2, 'PL0090'),
(3, 'PL0091'),
(4, 'DD0026'),
(5, 'DD0025')
) v(ord, ratecode)
order by ord;
然后请确保使用order by
进行选择:
select qom.*
from @QuestionOptionMapping qom
order by id;
请注意,这还使用了values()
表构造函数,这是一种非常方便的语法。
答案 2 :(得分:0)
如果您不从表格中进行选择?
然后,您可以插入VALUES,而不是带有并集的选择。
insert into @QuestionOptionMapping (RateCode) values
('PD0116')
,('PL0090')
,('PL0091')
,('DD0026')
,('DD0025')
或者在您的查询中,将所有UNION更改为UNION ALL。
UNION和UNION ALL之间的区别在于UNION将删除重复的行。
而UNION ALL只是从选择中抽出结果集。
为了使UNION能够找到这些重复项,首先必须在内部对其进行排序。
但是UNION ALL并不关心唯一性,因此不需要排序。
第三个选择是将一个插入语句更改为多个插入语句。
每个值一个插入。从而完全避免使用UNION。
但是,这种反高尔夫编码方法也最罗word。
答案 3 :(得分:0)
您的问题是您没有按照您的认为的顺序排列它们。 UNION仅是不同的值,通常会对这些值进行排序以促进不同。单独运行select语句,您将看到。
如果您使用values
进行插入,则会保留订单:
insert into @QuestionOptionMapping (RateCode) values
('PD0116'), ('PL0090'), ('PL0091'), ('DD0026'), ('DD0025')
select * from @QuestionOptionMapping order by ID