sql >> データベース >  >> RDS >> PostgreSQL

正規表現でテーブルを結合する方法

    @Milenがすでに述べたようにregexp_matches() おそらくあなたの目的にとって間違った機能です。単純な正規表現の一致( ) 。実際には、 LIKE演算子( ~~ 速くなります :

    おそらくLIKEで最速

    SELECT msg.message
          ,msg.src_addr
          ,msg.dst_addr
          ,mnc.name
    FROM   mnc
    JOIN   msg ON msg.src_addr ~~ ('%38' || mnc.code || '%')
               OR msg.dst_addr ~~ ('%38' || mnc.code || '%')
    WHERE  length(mnc.code) = 3
    

    さらに、必要なのは mnc.codeだけです。 正確に3文字です。

    正規表現あり

    あなたはできた 正規表現でも同じように記述しますが、間違いなく遅くなります。これがあなたのオリジナルに近い実用的な例です:

    SELECT msg.message
          ,msg.src_addr
          ,msg.dst_addr
          ,mnc.name
    FROM   mnc
    JOIN   msg ON (msg.src_addr || '+' || msg.dst_addr) ~ (38 || mnc.code)
               AND length(mnc.code) = 3
    

    これにはmsg.src_addrも必要です およびmsg.dst_addr NOT NULLである 。

    2番目のクエリは、追加のチェック length(mnc.code)=3がどのように行われるかを示しています。 JOINに入ることができます 条件またはWHERE 句。ここでも同じ効果があります。

    regexp_matches()を使用

    あなたはできた regexp_matches()を使用してこれを機能させます

    SELECT msg.message
          ,msg.src_addr
          ,msg.dst_addr
          ,mnc.name
    FROM   mnc
    JOIN   msg ON EXISTS (
        SELECT * 
        FROM   regexp_matches(msg.src_addr ||'+'|| msg.dst_addr, '38(...)', 'g') x(y)
        WHERE  y[1] = mnc.code
        )
    

    しかし、それに比べると遅くなるでしょう-またはそう思います。

    説明:
    regexp_matches()式は、最初ののキャプチャされたすべてのサブストリングの配列を返すだけです。 マッチ。 1つのサブストリング(パターン内の1組のブラケット)のみをキャプチャするため、1つの要素を持つ配列のみを取得します。 。

    すべての一致を取得します 追加の「グローバル」スイッチ'g' -しかし、複数の行にあります。したがって、それらすべて(または集計)をテストするには、副選択が必要です。それをEXISTSに入れてください -セミジョインすると、必要なものに到達します。

    たぶん、パフォーマンステストで報告することができます 3つすべてのうち? EXPLAINANALYZE を使用します そのために。



    1. 関数のパラメータとしてデータ型を渡すSQL Server 2008

    2. PHPおよびMySQLからヒンディー語のUnicodeデータをフェッチできません

    3. 1つのSQLクエリに複数の行を挿入する方法–今週のインタビュー質問#069

    4. GoogleCloudSQLは読み取り専用になりました