Консолидация значений и удаление дубликатов в соединительной таблице с использованием CTE - PullRequest
0 голосов
/ 21 апреля 2010

У меня есть следующая схема:

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

Пользователь данных хочет объединить Segments.Names и предоставил мне список текущих Segment.Names, сопоставленных с новым Segment.Names (все из которых существуют в настоящее время).

Так что теперь у меня есть этот список во временной таблице с currentID и newID для сопоставления.

Что я хочу сделать, это обновить SegmentID в SegmentsParcels на основе этой карты. Я мог бы использовать утверждение:

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

но это создаст несколько дубликатов. У меня есть уникальное ограничение на ParcelID и SegmentID в SegmentParcels.

Как лучше всего это сделать? Я подумал об удалении ограничения, а затем занялся удалением дубликатов (что я сделал в один момент и, вероятно, мог бы повторить снова), но я надеялся, что есть более простой способ.

Ответы [ 2 ]

0 голосов
/ 21 апреля 2010

Я закончил тем, что снял ограничение и удалил дубликаты, используя общее табличное выражение.
Вот 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
0 голосов
/ 21 апреля 2010

попробуйте что-то вроде этого:

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

Я добавил предложение OUTPUT SQL Server 2005 и более поздних версий только потому, что это может быть полезно, если у вас запущен большой скрипт. Таким образом, у вас есть старые и новые значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...