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

サブクエリの結果に正規表現を使用するにはどうすればよいですか?

    次のクエリのいずれかを試してください:

    SELECT a.phone_no
    FROM admission a
    JOIN users u on a.phone_no LIKE concat(u.phone_no, '__')
    WHERE u.phone_no REGEXP  '^(99)+[0-9]+$'
    

    または

    SELECT a.phone_no
    FROM admission a
    JOIN users u on a.phone_no REGEXP concat('^', u.phone_no, '[0-9]{2}$')
    WHERE u.phone_no REGEXP  '^(99)+[0-9]+$'
    

    「末尾の桁数」が固定されていない場合は、次を使用することもできます。

    LIKE concat(u.phone_no, '%')
    

    または

    REGEXP concat('^', u.phone_no, '[0-9]*$')
    

    ただし、この場合、SELECT DISTICT a.phone_noを使用する必要がある場合があります users.phone_noが可能であれば 他のusers.phone_noのサブシーケンスです (例:99123および991234)。

    更新

    ユーザーテーブルに10K行、アドミッションテーブルに100K行を使用していくつかのテストを実行した後、次のクエリが表示されました。

    SELECT a.phone_no
    FROM admission a
    JOIN users u 
        ON  a.phone_no >= u.phone_no
        AND a.phone_no < CONCAT(u.phone_no, 'z')
        AND a.phone_no LIKE CONCAT(u.phone_no, '%')
        AND a.phone_no REGEXP CONCAT('^', u.phone_no, '[0-9]*$')
    WHERE   u.phone_no LIKE  '99%'
        AND u.phone_no REGEXP  '^(99)+[0-9]*$'
    UNION SELECT 0 FROM (SELECT 0) dummy WHERE 0
    

    フィドル

    このようにして、REGEXPを使用できます それでも素晴らしいパフォーマンスがあります。このクエリは、私のテストケースではほぼ瞬時に実行されます。

    論理的には、REGEXP条件のみが必要です。ただし、大きなテーブルでは、クエリがタイムアウトする可能性があります。 LIKE条件を使用すると、REGEXPチェックの前に結果セットがフィルタリングされます。しかし、LIKEを使用しても、クエリはあまりうまく機能しません。何らかの理由で、MySQLは結合に範囲チェックを使用しません。そこで、明示的な範囲チェックを追加しました:

        ON  a.phone_no >= u.phone_no
        AND a.phone_no < CONCAT(u.phone_no, 'z')
    

    このチェックを使用すると、JOINパーツからLIKE条件を削除できます。

    UNIONパーツはDISTICTの代替品です。 MySQLはDISTINCTをGROUPBYステートメントに変換しているようですが、これはうまく機能しません。空の結果セットでUNIONを使用すると、SELECTの後に重複を削除するようにMySQLに強制します。末尾の数字を固定数で使用する場合は、その行を削除できます。

    必要に応じてREGEXPパターンを調整できます:

    ...
        AND a.phone_no REGEXP CONCAT('^', u.phone_no, '[0-9]{2}$')
    ...
        AND u.phone_no REGEXP  '^(99)+[0-9]{8}$'
    ...
    

    phone_noの長さをチェックするためにREGEXPのみが必要な場合は、「_」プレースホルダーでLIKE条件を使用することもできます。

        AND a.phone_no LIKE CONCAT(u.phone_no, '__')
    ...
        AND u.phone_no LIKE '99________$'
    

    または、LIKE条件をSTR_LENGTHチェックと組み合わせます。



    1. MySQLClosureTable階層型データベース-正しい順序で情報を引き出す方法

    2. クエリによって返された行ごとにストアドプロシージャを1回実行するにはどうすればよいですか?

    3. SQLServerのトリガーのリストを返す

    4. 1から始まるid列を再度更新する方法