4

PostgreSQL テーブルのデータをクリーンアップしようとしていますが、一部のレコードの列に多数の冒とく的な表現が含まれていemail_addressます (問題のレコードは、バグによる不満の結果として興奮したユーザーによって入力されましたが、その後修正されました) ):

    ┌────────────────────┐
    │メールアドレス│
    ├────────────────────┤
    │ foo@go.bar.me.net │
    │ foo@foo.com │
    │ foo@example.com │
    │ baz@example.com │
    │ barred@qux.com │
    └────────────────────┘

目的のクエリ出力

データ テーブルの各行に冒とく的なスコアで注釈を付け、スコアでレコードを並べ替えるクエリを作成して、人間が注釈付きデータ (Web アプリに表示される) を調べて必要なアクションを実行できるようにしたいと考えています。 :

    ┌────────────────────┬────────┐
    │ メールアドレス │ スコア │
    ├────────────────────┼────────┤
    │ foo@foo.com │ 18 │
    │ foo@go.bar.me.net │ 14 │
    │ foo@example.com │ 9 │
    │ baz@example.com │ 3 │
    │ barred@qux.com │ 0 │
    └────────────────────┴────────┘

試み #1

私が取っているアプローチは、正規表現のリストを作成することです (今は 2 つの問題があります...) とスコアです。これにより、email_address 列にその単語が見つかった場合、非常に冒とく的な単語が大きな冒涜スコアに寄与します。私profanitiesのテーブルは次のようになります。

    ┌──────────────────┬────────┐
    │ profanity_regexp │ スコア │
    ├──────────────────┼────────┤
    │ ふー │ 9 │
    │ バー(?!赤) │ 5 │
    │バズ│3│
    └──────────────────┴────────┘

ラテラルジョイン

LATERAL関数の結合を使用してregexp_matches、それぞれからすべての冒とく的な表現を抽出できることがわかりましたemail_address(ただし、冒とく的な表現のないレコードは破棄されます)。

SELECT
    data.email_address,
    array_agg(matches)
FROM
    data,
    profanities p,
    LATERAL regexp_matches(data.email_address, p.posix_regexp, 'gi') matches
GROUP BY
    data.email_address;

これにより、次の結果が生成されます。

    ┌────────────────────┬────────────────────┐
    │ email_address │ profanities_found │
    ├────────────────────┼────────────────────┤
    │ foo@foo.com │ {{foo},{foo}} │
    │ foo@example.com │ {{foo}} │
    │ foo@go.bar.me.net │ {{foo},{bar}} │
    │ baz@example.com │ {{baz}} │
    └────────────────────┴────────────────────┘

サブセレクト

また、次の SQL を使用して、各レコードの冒涜スコアの小計の配列を取得する方法も見つけました。

SELECT
    data.email_address,
    array(
        SELECT score * ( 
            SELECT COUNT(*)
            FROM (SELECT
                regexp_matches(data.email_address, p.posix_regexp, 'gi')
            ) matches
        )
        FROM profanities p
    ) prof
from data;

次のように、すべての行 (冒涜のない行を含む) を正しく生成します。

    ┌────────────────────┬──────────┐
    │ メールアドレス │ 教授 │
    ├────────────────────┼──────────┤
    │ foo@go.bar.me.net │ {9,5,0} │
    │ foo@foo.com │ {18,0,0} │
    │ foo@example.com │ {9,0,0} │
    │ baz@example.com │ {0,0,3} │
    │ barred@qux.com │ {0,0,0} │
    └────────────────────┴──────────┘

問題

横結合の結果を合計して目的の出力を得るにはどうすればよいですか?

望ましい結果を得るために使用できる別の戦略はありますか?


この質問のライブ コード フィドルをhttp://sqlfiddle.com/#!17/6685c/4に投稿しました。

4

3 に答える 3