最適な一致を選択するために必要な一連のデータがあります。各レコードには Name と CNum があります。同じ「名前」を持つ各レコードには、同じ「CNum」が必要です。実際には、一部の 'Name' 一致は同じ CNum を持ち、一部はそうではありません (これは解決すべき問題です)。どの CNum が優れているかを判断し、すべての「名前」の一致を 1 つの CNum で更新する必要があります。
一致する名前を表示する ParentId 列と、一致する 'Name' と 'CNum' をマークする SubParentId を使用してテーブルを更新し、目的の結果を抽出できるようにしました (また、一致を簡単に確認できるようにします)。
「Name」グループ内でどの CNum が他の CNum よりも優れているかを判断するために、各レコードは「ScoreA」と「ScoreB」の 2 つの列でスコア付けされています。スコアが低いほど良い。どの CNum が最適かを判断するために使用しているルールは次のとおりです。
- 名前グループ (同じ ParentId) のすべてのレコードが同じ CNum (同じ SubParentId) を持っている場合、何もしません。
- 同じ Name グループ内に同じ CNum がない場合は、ScoreA が 1 つだけ低いレコードの ID を選択し、グループの parentId を選択した ID に更新します。
- ScoreA の一致が 1 つもない場合は、各グループの parentId を、最低の ScoreB が 1 つあるレコードの ID で更新します。
- ScoreB の一致が 1 つもなく、異なる地域間で引き分けであり、そのうちの 1 つだけが「AB」地域を持つ場合、グループの各 parentId を、地域が「AB」のレコードの ID で更新します。
- それでも一致しない場合、または複数の '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