2

このテーブルがあると想像してください:

declare @tmpResults table ( intItemId int, strTitle nvarchar(100), intWeight float )

insert into @tmpResults values (1, 'Item One', 7)
insert into @tmpResults values (2, 'Item One v1', 6)
insert into @tmpResults values (3, 'Item Two', 6)
insert into @tmpResults values (4, 'Item Two v1', 7)

そして、2 つの文字列を受け取る fn_Lev と呼ぶ関数は、それらを互いに比較し、それらの差の数を整数 (つまり、レーベンシュタイン距離) として返します。

そのテーブルにクエリを実行し、各 strTitle の fn_Lev 値をテーブル内の他のすべての strTitle と比較してチェックし、3 のレーベンシュタイン距離で互いに類似している行を削除する最も効率的な方法は何ですか?

したがって、削除後、 @tmpResults には含まれている必要があります

1   Item One    7
4   Item Two v1 7

私はこれを行う方法を考えることができますが、恐ろしく遅くないものは何もありません(つまり、反復的です)。もっと速い方法があると確信していますか?

乾杯、マット

4

2 に答える 2

3
SELECT strvalue= CASE 
                WHEN t1.intweight >= t2.intweight THEN t1.strtitle 
                ELSE t2.strtitle 
              END, 
       dist = Fn_lev(t1.strtitle, t2.strtitle) 
FROM   @tmpResults AS t1 
       INNER JOIN @tmpResults AS t2 
         ON t1.intitemid < t2.intitemid 
WHERE  Fn_lev(t1.strtitle, t2.strtitle) = 3 

これにより、各行に 1 回だけ一致する自己結合が実行されます。行自体の一致、または前の一致の逆を除外します。つまり、A<->B が一致する場合、B<->A は一致しません。

case ステートメントは、最も加重された結果を選択します

于 2012-09-27T13:18:04.177 に答える
3

私があなたを正しく理解していれば、クロス結合を使用できます

SELECT t1.intItemId AS Id1, t2.intItemId AS Id2,  fn_Lev(t1.strTitle, t2.strTitle) AS Lev
FROM @tmpResults AS t1
CROSS JOIN @tmpResults AS t2

クロス結合は、結合の左側と右側の間の行のすべての組み合わせの結果を提供します (したがって、すべてを他のすべてに一致させるため、ON 句は必要ありません)。次に、SELECT の結果を使用して、削除するものを選択できます。

于 2012-09-27T13:06:04.467 に答える