0

最適な一致を選択するために必要な一連のデータがあります。各レコードには Name と CNum があります。同じ「名前」を持つ各レコードには、同じ「CNum」が必要です。実際には、一部の 'Name' 一致は同じ CNum を持ち、一部はそうではありません (これは解決すべき問題です)。どの CNum が優れているかを判断し、すべての「名前」の一致を 1 つの CNum で更新する必要があります。

一致する名前を表示する ParentId 列と、一致する 'Name' と 'CNum' をマークする SubParentId を使用してテーブルを更新し、目的の結果を抽出できるようにしました (また、一致を簡単に確認できるようにします)。

「Name」グループ内でどの CNum が他の CNum よりも優れているかを判断するために、各レコードは「ScoreA」と「ScoreB」の 2 つの列でスコア付けされています。スコアが低いほど良い。どの CNum が最適かを判断するために使用しているルールは次のとおりです。

  1. 名前グループ (同じ ParentId) のすべてのレコードが同じ CNum (同じ SubParentId) を持っている場合、何もしません。
  2. 同じ Name グループ内に同じ CNum がない場合は、ScoreA が 1 つだけ低いレコードの ID を選択し、グループの parentId を選択した ID に更新します。
  3. ScoreA の一致が 1 つもない場合は、各グループの parentId を、最低の ScoreB が 1 つあるレコードの ID で更新します。
  4. ScoreB の一致が 1 つもなく、異なる地域間で引き分けであり、そのうちの 1 つだけが「AB」地域を持つ場合、グループの各 parentId を、地域が「AB」のレコードの ID で更新します。
  5. それでも一致しない場合、または複数の 'AB' 領域 (異なる CNum と引き分けのスコアを持つ) の場合、その 'Name' グループ内の各レコードに対して NoBestMatch=1 を設定します

仮定: Name と CNum が同じ場合、スコアは同じになります。

上記のルールを適用して、探している結果を得る良い方法はありますか?

以下は、私が探しているデータと結果のサンプルです。insert ステートメントの横に、期待される勝利の結果が示されています。

-- create table
CREATE TABLE Results
(
    Id          INT NOT NULL IDENTITY( 1, 1 ) PRIMARY KEY,
    Name        VARCHAR(200) NULL,
    CNum        NVARCHAR(100) NULL,
    Region      NVARCHAR(3) NULL,
    ScoreA      INT NULL,
    ScoreB      INT NULL,
    ParentId    INT NULL,
    SubParentId INT NULL,
    NoMatch     BIT NOT NULL DEFAULT(0)
)
GO

-- insert data

-- Leave as is: they are all the same
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Grasslands', '91588', 'WY', '-668', '13' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB )
    VALUES ( 'Grasslands', '91588', 'WY', '-668', '13' )

--  Acme Co: winner noted below --> best ScoreA
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Acme Co', '269415003', 'AB', '-13455', '-23' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Acme Co', '269415003', 'AB', '-13455', '-23' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Acme Co', '5695003', 'AB', '-155', '-23' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Acme Co', '269415003', 'AB', '-13460', '-23' ) -- Expected Winner
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Acme Co', '5695003', 'AB', '-155', '-23' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Acme Co', '5695003', 'AB', '-155', '-23' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Acme Co', '856545', 'AB', '-22', '16' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Acme Co', '856545', 'AB', '-22', '16' )

--  Zuland Ltd: winner noted below --> best ScoreB
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Zuland Ltd', '654543', 'AB', '-13455', '-28' )    
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Zuland Ltd', '654543', 'AB', '-13455', '-28' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Zuland Ltd', '654543', 'AB', '-13455', '-23' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Zuland Ltd', '5603', 'ON', '-13455', '-30' )  -- Expected Winner
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Zuland Ltd', '5603', 'ON', '-13455', '-23' )

--  Emco Inc: winner noted below --> AB tie breaker
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Emco Inc', '5695003', 'ON', '-668', '13' )    
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Emco Inc', '5695003', 'AB', '-668', '13' ) -- Expected Winner
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Emco Inc', '5545', 'CA', '-668', '13' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Emco Inc', '5545', 'CA', '-668', '13' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Emco Inc', '995588', 'WY', '-668', '13' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Emco Inc', '995588', 'WY', '-668', '13' )

-- Zemco Inc: No Winner --> No AB tie breaker
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Zemco Inc', '5695003', 'TN', '-668', '13' )   
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB )
    VALUES ( 'Zemco Inc', '5695003', 'TN', '-668', '13' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Zemco Inc', '5545', 'CA', '-668', '13' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB )
    VALUES ( 'Zemco Inc', '995588', 'WY', '-668', '13' )

-- Texco Inc: No Winner --> No AB tie breaker
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Texco Inc', '234JJJ', 'TN', '-668', '13' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Texco Inc', '555552', 'TN', '-668', '13' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Texco Inc', '234JJJ', 'CA', '-668', '13' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Texco Inc', '555552', 'WY', '-668', '13' )

-- Grasslands: Leave as is --> they are all the same
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Grasslands', '91588', 'WY', '-668', '13' )    
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB )
    VALUES ( 'Grasslands', '91588', 'WY', '-668', '13' )

-- Mike Inc: No Match --> more than 1 'AB' with tied scores
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Mike Inc', '234JJJ', 'AB', '-668', '13' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Mike Inc', '555552', 'AB', '-668', '13' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Mike Inc', '234JJJ', 'AB', '-668', '13' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB )
    VALUES ( 'Mike Inc', '555552222', 'WY', '-668', '13' )
INSERT INTO Results ( Name, CNum, Region, ScoreA, ScoreB ) 
    VALUES ( 'Mike Inc', '90210', 'KT', '-668', '13' )

GO

-- set parent id matched on Name
UPDATE  r
SET     r.ParentId = COALESCE( r1.Id, r.Id )
FROM    Results r
LEFT JOIN Results r1
  ON    r.Name = r1.NAME
GO

-- set sub-parent id matched on Name and CNum
UPDATE  r
SET     r.SubParentId = COALESCE( r1.Id, r.Id )
FROM    Results r
LEFT JOIN Results r1
  ON    r.Name = r1.Name AND
        r.CNum = r1.CNum
GO
4

1 に答える 1