我的陈述看起来像这样:
MERGE INTO someTable st
USING
(
SELECT id,field1,field2,etc FROM otherTable
) ot on st.field1=ot.field1
WHEN NOT MATCHED THEN
INSERT (field1,field2,etc)
VALUES (ot.field1,ot.field2,ot.etc)
其中 otherTable 具有自动增量 id 字段。
我希望插入 someTable 的顺序与 otherTable 的 id 字段的顺序相同,以便插入不匹配字段时,将保留 id 的订单。
快速查看docs似乎表明没有任何功能可以支持此功能。
这可能,还是有另一种方法可以完成符合我要求的插入?
编辑:一种方法是向 someTable 添加一个捕获排序的附加字段。如果可能的话,我宁愿不这样做。
...经过反思,上面的方法似乎是要走的路。
答案 0 :(得分:13)
我无法说出提问者在这里要求的内容,因为它没有 任何 感。
让我们说,我有一个没有身份字段的堆表,但它确实有一个" 访问"日期字段。
堆表记录人员WebPage访问,并将其加载到我的数据仓库中
在此数据仓库中,我想使用Surrogate-Key" WebHitID "引用这些关系。
让我们使用Merge进行表的初始加载,然后继续调用它以使表保持同步。
我知道如果我将记录插入表中,那么我更喜欢ID(由Identify-Field生成)依据我选择的Order-By顺序排列(让我们说" 访问"日期)。
期望Integer-ID与相对于表中其余记录的创建时间相关联的情况并不少见。
我知道这并非总是百分之百的情况,但是让我感到幽默。
使用(感觉像 hack )TOP将允许在我们的插入中进行排序:
MERGE DW.dbo.WebHit AS Target --This table as an Identity Field called WebHitID.
USING
(
SELECT TOP 9223372036854775807 --Biggest BigInt (to be safe).
PWV.PersonID, PWV.WebPageID, PWV.Visited
FROM ProdDB.dbo.Person_WebPage_Visit AS PWV
ORDER BY PWV.Visited --Works only with TOP when inside a MERGE statement.
) AS Source
ON Source.PersonID = Target.PersonID
AND Source.WebPageID = Target.WebPageID
AND Source.Visited = Target.Visited
WHEN NOT MATCHED BY Target THEN --Not in Target-Table, but in Source-Table.
INSERT (PersonID, WebPageID, Visited) --This Insert populates our WebHitID.
VALUES (Source.PersonID, Source.WebPageID, Source.Visited)
WHEN NOT MATCHED BY Source THEN --In Target-Table, but not in Source-Table.
DELETE --In case our WebHit log in Prod is archived/trimmed to save space.
;
你可以看到我选择使用TOP 9223372036854775807(最大的整数)来拉动所有东西。
如果你有更多的资源合并,那么你应该把它分块。
虽然这会尖叫" hacky workaround "对我来说,它应该让你到达你需要去的地方
我在一个小样本集上对此进行了测试并验证了它的工作原理。
我没有研究它对更大的复杂数据集的性能影响,所以YMMV有和没有TOP。
答案 1 :(得分:6)
跟进MikeTeeVee的回答。
使用TOP将允许您在子查询中进行排序,但不是TOP 9223372036854775807
,而是使用
SELECT TOP 100 PERCENT
不太可能达到这个数字,但这种方式更有意义,看起来更干净。
答案 2 :(得分:-4)
为什么你会关心id匹配的顺序?您对查询数据的方式有何不同?相关表应通过主键和外键连接,而不是插入订单记录。在数据库中,表并不是以特定方式进行的。订单应来自order by子句。
更多解释为什么要这样做可能会帮助我们引导您找到合适的解决方案。