0

Il doit y avoir une meilleure façon de procéder.Enregistrement TSQL en double avec un seul identifiant unique

J'ai une table que je hélé tous les enregistrements uniques comme celui-ci:

WITH 
    CTE(TransId, OriginalName, StrippedName, RowNumber) 
    AS 
    (
     SELECT TransID , 
       Name , 
       StrippedName, 
       RN = ROW_NUMBER() OVER (PARTITION BY StrippedName ORDER BY StrippedName) 
     FROM dbo.Members 
    ) 

UPDATE dbo.Members 
SET ParenId = TransID 
WHERE TransID IN (SELECT TransId FROM CTE WHERE RowNumber = 1) 

Maintenant, je voudrais mettre à jour tous les enregistrements de doublons (où RowNumber> 1) au ParentId unique. En ce moment j'utilise un UDF, qui fonctionne, mais cela prend beaucoup de temps. Voici l'UDF:

CREATE FUNCTION dbo.getParentTransId (@TransId INT, @strippedBusName VARCHAR(200)) 
RETURNS INT 
AS 
BEGIN 
    DECLARE @ParentTransId INT 

    SELECT @ParentTransId = TransId 
    FROM dbo.Members 
    WHERE StrippedBusName = @strippedBusName 
     AND ParenId IS NOT NULL 

    IF @ParentTransId IS NULL 
    BEGIN 
     SET @ParentTransId = @TransId 
    END 

    RETURN @ParentTransId 
END 
GO 

Et voici la déclaration de mise à jour J'utilise actuellement:

UPDATE dt 
SET dt.ParenId = dbo.getParentTransId (dt.TransID, dt.StrippedBusName) 
FROM dbo.Members dt 
GO 

Est-il possible de faire la même mise à jour sans utiliser l'UDF?

Répondre

0

Je suppose que cela devrait fonctionner:

UPDATE dbo.Members dt 
SET dt.ParenId = COALESCE((SELECT TrandsID FROM dbo.Members WHERE dt.StrippedBusName = StrippedBusName AND ParenId IS NOT NULL), dt.TransId) 

et je ne suis pas sûr, mais la façon suivante, devrait être un plus rapide:

UPDATE dbo.Members dt 
SET dt.ParenId = COALESCE(dt1.TransId, dt.TransId) 
FROM dbo.Members dt 
LEFT JOIN dbo.Members dt1 
    ON dt.StrippedBusName = dt1.StrippedBusName 
    AND dt1.ParenId IS NOT NULL 
+0

Nice! Encore mieux si je cours la dernière mise à jour suggérée sans le "AND dt1.ParentId IS NOT NULL", je n'ai pas besoin d'exécuter ma première mise à jour pour signaler les uniques. – mwhib

1

Voici un script de test qui montre réponse @gotqn travaux:

-- create table 
CREATE TABLE DupUpdateTest 
(
    Id  INT NOT NULL PRIMARY KEY IDENTITY(1, 1), 
    TransId INT NOT NULL, 
    OriginalName VARCHAR(MAX), 
    StrippedName VARCHAR(MAX), 
    ParentId INT NULL 
) 
GO 

-- insert data 
INSERT INTO dbo.DupUpdateTest VALUES (2, 'name 1', 'name1', NULL) 
INSERT INTO dbo.DupUpdateTest VALUES (3, 'name 1', 'name1', NULL) 
INSERT INTO dbo.DupUpdateTest VALUES (6, 'name 1', 'name1', NULL) 
INSERT INTO dbo.DupUpdateTest VALUES (8, 'name 2', 'name2', NULL) 
INSERT INTO dbo.DupUpdateTest VALUES (11, 'name 2', 'name2', NULL) 
INSERT INTO dbo.DupUpdateTest VALUES (15, 'name 55', 'name55', NULL) 
INSERT INTO dbo.DupUpdateTest VALUES (23, 'name 55', 'name55', NULL) 
INSERT INTO dbo.DupUpdateTest VALUES (99, 'name 100', 'name100', NULL) 
INSERT INTO dbo.DupUpdateTest VALUES (122, 'name 108', 'name108', NULL) 

-- update parent id match 
UPDATE dt 
SET dt.ParentId = COALESCE(dt1.TransId, dt.TransId) -- Returns the first nonnull expression among its arguments 
FROM dbo.DupUpdateTest dt 
LEFT JOIN dbo.DupUpdateTest dt1 
    ON dt.StrippedName = dt1.StrippedName 

-- view results 
SELECT * FROM dbo.DupUpdateTest 
+0

+1 Et je suis content d'avoir pu aider. – gotqn

Questions connexes