0

je le schéma suivant:les valeurs et la consolidation des doublons dans une suppression table de jonction à l'aide CTE

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

Un utilisateur des données veut consolider Segments.Names et m'a donné une liste de Segment.Names en cours mis en correspondance new Segment.Names (tous existant actuellement). J'ai maintenant cette liste dans une table temporaire avec les identifiants currentID et newID pour mapper vers. Ce que je veux faire est de mettre à jour le SegmentID dans SegmentsParcels basé sur cette carte. Je pourrais utiliser la déclaration:

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

mais cela va créer des doublons que j'ai une contrainte unique sur ParcelID et SegmentID dans SegmentParcels.

Quelle est la meilleure façon de procéder? J'ai envisagé de supprimer la contrainte puis de supprimer les doublons (ce que j'ai fait à un moment donné et que je pourrais probablement refaire) mais j'espérais qu'il y aurait un moyen plus simple.

Répondre

0

J'ai fini par abandonner la contrainte et supprimer les doublons en utilisant une expression de table commune.
Voici le sql je:

-- 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

essayer quelque chose comme ceci:

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 

j'ai jeté dans la clause de sortie qui est SQL Server 2005 et, juste parce qu'il pourrait être utile si vous avez un grand scénario en cours d'exécution. De cette façon, vous avez les anciennes et les nouvelles valeurs.

+0

Hmm. Il y a quelque chose qui ne va pas avec ça et je ne suis pas assez aiguisé pour le saisir. Je continue à obtenir des résultats zéro sur la sous-requête select puisque parcelid n'est jamais nul. – earthling

Questions connexes