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

MySQL REPLACE:同じヘッドとテールで区切られたすべての個別のサブストリング内のcharのすべての出現をどのように置き換えるか

    純粋なMySQLでは、本格的なHTMLパーサーまたはREGEX_REPLACE関数をMySQLにインポートするUDFを使用せずにのみ可能です。

    秘訣は、数値ジェネレーターを使用し、ネストされたSUBSTRING_INDEXを使用してhtmlタグの大きな文字列を分割することです
    この数値ジェネレーターは1から10.000までの数値を生成します
    したがって、「パーサー」は最大10.000タグがさらに必要な場合は、さらに追加する必要があります

    CROSS JOIN (
         SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
        ) AS record_[number]
    

    クエリ

    SELECT 
     (@number := @number + 1) AS number
    FROM (    
      SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
    ) AS record_1
    CROSS JOIN (
      SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
    ) AS record_2
    CROSS JOIN (
     SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
    ) AS record_3
    CROSS JOIN (
      SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
    ) AS record_4
    CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
    

    このSQLステートメントは、htmlタグで分割するために使用されます

    SQLステートメント

    CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX([large_html_string], ">", [tag_position]), ">", -1), ">") as tag 
    

    ここでの秘訣は、数値ジェネレーターとhtml文字列splittigを組み合わせることです。したがって、[tag_position]は数値ジェネレーターからの数値で埋められます。
    これは、CROSSJOINを使用して行われます。

    クエリ

    SELECT 
     *
    FROM ( 
    
      SELECT 
        CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(data, ">", generator.number), ">", -1), ">") as tag 
      FROM (
    
        SELECT '<p><span><b>C10373 - FIAT GROUP AUTOMOBILES/RAMO DI AZIENDA DI KUEHNE + NAGEL</b></span>
        <p>la somma pari a € 400+IVA per l’attività</p>
        <p>TELE+ A 20.000 LIRE AL MESE </p>
        <li>a mano o via fax al numero +39.00.0.0.0.00.</li>
        <p>Il punteggio base sarà incrementato di un <strong>+ </strong>al ricorrere di ciascuna delle seguenti condizioni:</p>
        <li><a href="/aaa/gare/CIGZB81E5568D+RDO1560277+Obblighi+contattuali-signed.pdf" title="">Obblighi contrattuali</a></li> 
        <li><a href="/aaa/gare/CIGZB81E5568D+RDO1560277+Obblighi+contattuali-signed.pdf" title="">Obblighi contrattuali</a></li> 
        <li><a href="/aaa/gare/CIGZB81E5568D+RDO_1560277Lettera_Invito.pdf" title="">Lettera di invito</a></li>
        <li><a href="/aaa/gare/CIGZB81E5568D+RDO1560277+Obblighi+contattuali-signed.pdf" title="">Obblighi contrattuali</a></li> 
        <li><a href="/aaa/gare/CIGZB81E5568D+RDO1560277+disciplinare+di+gara-signed.pdf" title="">Disciplinare di gara</a></li>
        <li><a href="/aaa/gare/CIGZB81E5568D+determina+di+aggiudicazione+58+2017.pdf" title="">Determina di aggiudicazione</a></li>' AS data
    
       ) AS record 
       CROSS JOIN (
         SELECT 
           (@number := @number + 1) AS number
         FROM (    
           SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
         ) AS record_1
         CROSS JOIN (
           SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
         ) AS record_2
         CROSS JOIN (
           SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
         ) AS record_3
         CROSS JOIN (
           SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
         ) AS record_4
         CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
       ) 
        AS generator
     ) 
     AS tags
    WHERE 
     tags.tag != '>'
    

    デモを参照 http://www.sqlfiddle.com/#!9/de2ed/32

    これで、タグが分離されたレコードとして作成され、「href」を含むレコードでのみ置き換えるのが非常に簡単になりました。

    SQLステートメント

     (
        CASE 
          WHEN 
            LOCATE("href", tags.tag) > 0
          THEN 
            REPLACE(tags.tag, "+", " ") 
          ELSE 
            tags.tag
        END
     ) AS tag
    

    デモを参照 http://www.sqlfiddle.com/#!9/de2ed/38

    置き換える方法がわかったので、レコードを1つの文字列にマージして戻します。そのためにGROUP_CONCATを使用できます。

    クエリ

        SET SESSION group_concat_max_len = @@max_allowed_packet;
    
        SELECT 
         GROUP_CONCAT(
            CASE 
              WHEN 
                LOCATE("href", tags.tag) > 0
              THEN 
                REPLACE(tags.tag, "+", " ") 
              ELSE 
                tags.tag
            END
           SEPARATOR ""
         ) AS html
    
        FROM ( 
    
          SELECT 
            CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(data, ">", generator.number), ">", -1), ">") as tag 
          FROM (
    
            SELECT '<p><span><b>C10373 - FIAT GROUP AUTOMOBILES/RAMO DI AZIENDA DI KUEHNE + NAGEL</b></span>
            <p>la somma pari a € 400+IVA per l’attività</p>
            <p>TELE+ A 20.000 LIRE AL MESE </p>
            <li>a mano o via fax al numero +39.00.0.0.0.00.</li>
            <p>Il punteggio base sarà incrementato di un <strong>+ </strong>al ricorrere di ciascuna delle seguenti condizioni:</p>
            <li><a href="/aaa/gare/CIGZB81E5568D+RDO1560277+Obblighi+contattuali-signed.pdf" title="">Obblighi contrattuali</a></li> 
            <li><a href="/aaa/gare/CIGZB81E5568D+RDO1560277+Obblighi+contattuali-signed.pdf" title="">Obblighi contrattuali</a></li> 
            <li><a href="/aaa/gare/CIGZB81E5568D+RDO_1560277Lettera_Invito.pdf" title="">Lettera di invito</a></li>
            <li><a href="/aaa/gare/CIGZB81E5568D+RDO1560277+Obblighi+contattuali-signed.pdf" title="">Obblighi contrattuali</a></li> 
            <li><a href="/aaa/gare/CIGZB81E5568D+RDO1560277+disciplinare+di+gara-signed.pdf" title="">Disciplinare di gara</a></li>
            <li><a href="/aaa/gare/CIGZB81E5568D+determina+di+aggiudicazione+58+2017.pdf" title="">Determina di aggiudicazione</a></li>' AS data
    
           ) AS record 
           CROSS JOIN (
             SELECT 
               (@number := @number + 1) AS number
             FROM (    
               SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
             ) AS record_1
             CROSS JOIN (
               SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
             ) AS record_2
             CROSS JOIN (
               SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
             ) AS record_3
             CROSS JOIN (
               SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
             ) AS record_4
             CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
           ) 
            AS generator
         ) 
         AS tags
        WHERE 
         tags.tag != '>'
    

    完全なクエリについてはデモをご覧ください

    http://www.sqlfiddle.com/#!9/de2ed/46




    1. SQLiteはPRINTF()の名前をFORMAT()に変更します

    2. PIVOT、UNPIVOT、およびリバースPIVOTステートメントを理解する

    3. PostgreSQLをインストールできません:WindowsXPでMicrosoftVC++ランタイムインストーラーを実行するとエラーが発生しました

    4. エラー1356(HY000):ビュー'mysql.user'が無効なテーブルまたは列または関数を参照しているか、ビューの定義者/呼び出し元にそれらを使用する権限がありません