6

約18000行のテーブルを渡されました。各レコードには、1 人の顧客の場所が記述されています。問題は、その人がテーブルを作成したときに、「会社名」のフィールドを追加せず、「場所の名前」のみを追加したことであり、1 つの会社が多くの場所を持つことができます。

たとえば、同じ顧客を説明するいくつかのレコードを次に示します。

ロケーションテーブル

 ID  Location_Name     
 1   TownShop#1        
 2   Town Shop - Loc 2 
 3   The Town Shop     
 4   TTS - Someplace   
 5   Town Shop,the 3   
 6   Toen Shop4        

私の目標は、次のようにすることです。

ロケーションテーブル

 ID  Company_ID   Location_Name     
 1   1            Town Shop#1       
 2   1            Town Shop - Loc 2 
 3   1            The Town Shop     
 4   1            TTS - Someplace   
 5   1            Town Shop,the 3   
 6   1            Toen Shop4        

会社表

 Company_ID  Company_Name  
 1           The Town Shop 

「会社」テーブルはありません。複数の場所を表す最もわかりやすい、または最適な場所名から会社名リストを生成する必要があります。

現在、似ている場所名のリストを生成し、そのリストを手作業で調べる必要があると考えています。

これにどのようにアプローチできるかについての提案は大歓迎です。

@Neall、ご意見ありがとうございます。残念ながら、各場所の名前は異なります。重複する場所の名前はなく、似ているだけです。したがって、ステートメント「repcount」の結果では、各行で 1 になります。

@yukondude、あなたのステップ4は私の質問の核心です.

4

5 に答える 5

1

私は前にこれをしなければなりませんでした。それを行う唯一の実際の方法は、さまざまな場所を手動で一致させることです。データベースのコンソール インターフェイスとグループ化 select ステートメントを使用します。まず、「会社名」フィールドを追加します。それで:

SELECT count(*) AS repcount, "Location Name" FROM mytable
 WHERE "Company Name" IS NULL
 GROUP BY "Location Name"
 ORDER BY repcount DESC
 LIMIT 5;

リストの一番上にある場所が属している会社を特定し、会社名フィールドを UPDATE ... WHERE "Location Name" = "The Location" ステートメントで更新します。

PS - 会社名と場所名を別々のテーブルに分割し、それらを主キーで参照する必要があります。

更新: - うわー - 重複はありませんか? レコードは何枚持っていますか?

于 2008-08-08T16:40:43.933 に答える
1

質問を更新してください。利用可能な CompanyNames のリストはありますか? レーベンシュタインアルゴリズムを使用して、CompanyNames と LocationNames のリスト間の関係を見つけることができるかもしれないのでお願いします。


アップデート

会社名のリストはありません。複数の場所を表す最もわかりやすい、または最適な場所名から会社名を生成する必要があります。

わかりました...これを試してください:

  1. ほとんどまたはすべてがアルファベット文字で構成される LocationNames を見つけて、候補の CompanyNames のリストを作成します。これには正規表現を使用できます。このリストを別のテーブルに保存します。
  2. そのリストをアルファベット順に並べ替え、(手動で) どのエントリを CompanyNames にするかを決定します。
  3. 各 CompanyName を各 LocationName と比較し、一致スコアを見つけます (レーベンシュタインまたはその他の文字列一致アルゴリズムを使用します)。結果を別のテーブルに格納します。
  4. MatchScore < Threshold が特定の CompanyName の一致と見なされないように、しきい値スコアを設定します。
  5. CompanyName | LocationNames を手動で調べます。場所名 | MatchScore を調べて、どれが実際に一致するかを判断します。MatchScore で注文すると、プロセスの負担が軽減されます。

上記のアクションの全体的な目的は、部分を自動化し、問題の範囲を制限することです。完璧にはほど遠いですが、18K レコードを手作業で処理する手間が省けることを願っています。

于 2008-08-08T16:41:29.623 に答える
0

いくつかの複雑なトークン マッチング アルゴリズムを推奨するつもりでしたが、それを正しく行うのは非常に難しく、データに多くの相関関係 (入力ミスなど) がない場合は、あまり良い結果が得られません。

ジョブをAmazon Mechanical Turkに送信し、人間に任せることをお勧めします。

于 2008-08-08T16:44:48.480 に答える
0

理想的には、Company という名前の別のテーブルが必要であり、この "Location" テーブルに company_id 列が必要です。これは、Company テーブルの主キー (おそらく id と呼ばれる) への外部キーです。これにより、このテーブルでかなりのテキストの重複が回避されます (18,000 行を超える場合、整数の外部キーは varchar 列よりもかなりのスペースを節約できます)。

しかし、その Company テーブルをロードし、それを Location の行に適切に関連付ける方法にまだ直面しています。一般的な解決策はありませんが、次の方法で何かを行うことができます。

  1. 自動インクリメントする id 列を持つ Company テーブルを作成します (RDBMS によって異なります)。
  2. 一意の会社名をすべて見つけて、Company に挿入します。
  3. NULL を受け入れる列 company_id を Location に追加します (現時点では)。これは Company.id 列の外部キーです。
  4. Location の各行について、対応する会社を特定し、その行の company_id 列をその会社の ID で UPDATE します。これはおそらく最も困難なステップです。データが例に示したようなものである場合、さまざまな文字列一致アプローチを使用して、これを何度も実行する必要があります。
  5. Location のすべての行に company_id 値が設定されたら、Company テーブルを ALTER して、NOT NULL 制約を company_id 列に追加できます (すべての場所に会社が必要であると仮定すると、妥当と思われます)。

Location テーブルのコピーを作成できる場合は、一連の SQL ステートメントを徐々に作成して、company_id 外部キーを設定できます。間違えた場合は、最初からやり直して、失敗した時点までスクリプトを再実行できます。

于 2008-08-08T16:47:35.853 に答える
0

はい、前回の投稿のステップ 4 は大変です。

いずれにせよ、おそらくこれの一部は手作業で行う必要がありますが、大部分は自動化できる可能性があります。指定した場所の例では、次のようなクエリで適切な company_id 値が設定されます。

UPDATE  Location
SET     Company_ID = 1
WHERE   (LOWER(Location_Name) LIKE '%to_n shop%'
OR      LOWER(Location_Name) LIKE '%tts%')
AND     Company_ID IS NULL;

それはあなたの例と一致すると思います(IS NULL以前に設定した Company_ID 値を上書きしないように部分を追加しました)が、もちろん18,000行では、さまざまな組み合わせを処理するためにかなり独創的である必要があります.

Company の名前を使用して、上記のようなクエリを生成することも役に立ちます。次のようなことができます (MySQL で):

SELECT  CONCAT('UPDATE Location SET Company_ID = ',
        Company_ID, ' WHERE LOWER(Location_Name) LIKE ',
        LOWER(REPLACE(Company_Name), ' ', '%'), ' AND Company_ID IS NULL;')
FROM    Company;

次に、それが生成するステートメントを実行するだけです。それはあなたのために多くのグランジ作業を行うことができます.

于 2008-08-08T22:07:02.527 に答える