0

これを行うためのより良い方法が必要です。

次のように、すべての一意のレコードにフラグを立てたテーブルがあります。

    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 )

ここで、すべての重複レコード (RowNumber > 1) を一意の ParentId に更新したいと思います。現在、動作する UDF を使用していますが、非常に時間がかかります。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

そして、これが私が現在使用している更新ステートメントです。

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

UDF を使用せずに同じ更新を行う方法はありますか?

4

2 に答える 2

1

@gotqn の回答が機能することを示すテスト スクリプトを次に示します。

-- 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
于 2013-08-02T18:14:14.043 に答える
0

私はこれがうまくいくと思います:

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

よくわかりませんが、次の方法の方が高速です。

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
于 2013-08-02T07:28:03.400 に答える