0

我有以下架构:

Parcels       Segments        SegmentsParcels
=========     ==========      =================
ParcelID      SegmentID       ParcelID
...           Name            SegmentID
              ...             id

数据的用户想要合并 Segments.Names,并给了我一个映射到新 Segment.Names 的当前 Segment.Names 列表(所有这些当前都存在)。

所以现在我在一个临时表中有这个列表,其中包含要映射到的 currentID 和 newID。

我想做的是根据这张地图更新 SegmentsParcels 中的 SegmentID。我可以使用以下语句:

update SegmentParcels set segmentID = [newID] from newsegments where segmentID = currentid

但这会创建一些重复我对 SegmentParcels 中的 ParcelID 和 SegmentID 有唯一约束。

解决此问题的最佳方法是什么?我考虑删除约束,然后处理删除重复项(我曾经做过一次并且可能会再次这样做),但我希望有一种更简单的方法。

4

2 回答 2

0

尝试这样的事情:

CREATE TABLE #Results (oldID int, newid int)

update sp
    set segmentID = dt.newID
    OUTPUT sp.segmentID, dt.newID
        INTO #Results
    FROM SegmentParcels sp
    INNER JOIN (SELECT DISTINCT
                    segmentID, newID
                    FROM newsegments              ns 
                        INNER JOIN SegmentParcels sp ON ns.currentid = sp.segmentID
                        LEFT OUTER JOIN SegmentParcels sp2 ON ns.currentid = sp2.segmentID AND sp.ParcelID=sp2.ParcelID
                    WHERE sp2.ParcelID IS NULL

               ) dt ON dt.segmentID=sp.segmentID

我加入了 SQL Server 2005 及更高版本的 OUTPUT 子句,只是因为如果您正在运行大型脚本,它可能会有所帮助。这样你就有了旧值和新值。

于 2010-04-20T20:36:13.527 回答
0

我最终放弃了约束并使用公用表表达式删除了重复项。
这是我使用的sql:

-- drop unique constraint
ALTER TABLE [dbo].[SegmentParcels] DROP CONSTRAINT [uc_SegmentID_ParcelID]
GO

-- update segment ids to new values from map
update SegmentParcels
set segmentID = [newID] from newsegments where segmentID = currentid
GO

-- use common table expression to delete duplicates
WITH Duplicates(SegmentID, ParcelID, Id)
AS
(
    SELECT SegmentID, ParcelID, Min(Id) Id
    FROM SegmentParcels
    GROUP BY segmentID, parcelID
    HAVING Count(*) > 1
)
DELETE FROM SegmentParcels
WHERE Id IN (
    SELECT SegmentParcels.Id
    FROM SegmentParcels
    INNER JOIN Duplicates
    ON SegmentParcels.segmentID = Duplicates.SegmentID
    AND SegmentParcels.parcelID = Duplicates.ParcelID
    AND SegmentParcels.Id <> Duplicates.Id
) 

-- add unique constraint back
ALTER TABLE [dbo].[SegmentParcels] ADD  CONSTRAINT [uc_SegmentID_ParcelID] UNIQUE NONCLUSTERED 
(
    [segmentID] ASC,
    [parcelID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO
于 2010-04-21T17:59:56.437 回答