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

MySqlで特定のパターンの部分文字列を抽出します

    DBの仕事ではありません しかし、それは可能です:

    CREATE TABLE tab(id INT, col VARCHAR(100));           
    INSERT INTO tab(id, col) 
    VALUES (1, 'option[A]sum[A]g3et[B]'), (2, '[Cosi]sum[A]g3et[ZZZZ]');      
    
    SELECT DISTINCT *
    FROM (
      SELECT id, RIGHT(val, LENGTH(val) - LOCATE('[', val)) AS val
      FROM
      (
        SELECT id, SUBSTRING_INDEX(SUBSTRING_INDEX(t.col, ']', n.n), ']', -1) AS val
        FROM tab t 
        CROSS JOIN 
        (
         SELECT a.N + b.N * 10 + 1 n
           FROM 
          (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
          ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
        ) n
        WHERE n.n <= 1 + (LENGTH(t.col) - LENGTH(REPLACE(t.col, ']', '')))
      ) sub
    ) s
    WHERE val <> ''
    ORDER BY ID;
    

    SqlFiddleDemo

    注:

    colによって異なります CROSS JOINでより多くの数値を生成する必要がある場合がある最大長 セクション。今のところ100までです。

    出力:

    仕組み:

    1. CROSS JOINを使用して数値テーブルを生成します
    2. ]に基づいて文字列を分割します デリメータとして
    3. RIGHT(val, LENGTH(val) - LOCATE('[', val)) [までの部分を削除します
    4. 空のレコードを除外する
    5. DISTINCTのみを取得 値

    最も内側のクエリ:

    ╔════╦══════════╗
    ║ id ║   val    ║
    ╠════╬══════════╣
    ║  1 ║ option[A ║
    ║  1 ║ sum[A    ║
    ║  1 ║ g3et[B   ║
    ║  1 ║          ║
    ╚════╩══════════╝
    

    2番目のサブクエリ:

    ╔════╦═════╗
    ║ id ║ val ║
    ╠════╬═════╣
    ║  1 ║ A   ║
    ║  1 ║ A   ║
    ║  1 ║ B   ║
    ║  1 ║     ║
    ╚════╩═════╝
    

    そして最も外側のクエリ:

    ╔════╦═════╗
    ║ id ║ val ║
    ╠════╬═════╣
    ║  1 ║ A   ║
    ║  1 ║ B   ║
    ╚════╩═════╝
    

    簡単に追加してください:

    WHERE n.n <= 1 + (LENGTH(t.col) - LENGTH(REPLACE(t.col, ']', '')))
      AND t.id = ?
    

    編集2:

    MySQLでJSONを解析したいとします。 前に言ったように、アプリケーション層で解析して値を取得します。 この回答はデモ/おもちゃの目的のみであり、パフォーマンスは非常に低くなります。

    それでもSQLソリューションを主張する場合:

    SELECT id, val,s.n
    FROM (
      SELECT id, RIGHT(val, LENGTH(val) - LOCATE('[', val)) AS val,n
      FROM
      (
        SELECT id, SUBSTRING_INDEX(SUBSTRING_INDEX(t.col, ']', n.n), ']', -1) AS val, n.n
        FROM (SELECT id, REPLACE(col, '[]','') as col FROM tab) t
        CROSS JOIN 
        (
         SELECT e.N * 10000 + d.N * 1000 + c.N * 100 + a.N + b.N * 10 + 1 n
           FROM 
          (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
          ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
          ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) c
          ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) d
          ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) e
    
        ) n
        WHERE n.n <= 1 + (LENGTH(t.col) - LENGTH(REPLACE(t.col, ']', '')))
      ) sub
    ) s
    WHERE val <> ''
    GROUP BY id, val
    HAVING n <> MAX(n)
    ORDER BY id,n;
    

    SqlFiddleDemo

    出力:

    ╔═════╦═════════════╦════╗
    ║ id  ║    val      ║ n  ║
    ╠═════╬═════════════╬════╣
    ║  1  ║ CE31285LV4  ║  1 ║
    ║  1  ║ D32E        ║  3 ║
    ║  1  ║ GTX750      ║  5 ║
    ║  1  ║ M256S       ║  7 ║
    ║  1  ║ H2X1T       ║  9 ║
    ║  1  ║ FMLANE4U4   ║ 11 ║
    ╚═════╩═════════════╩════╝
    

    編集3:

    CROSS JOIN サブクエリ全体は集計テーブルのみです。それがすべてです。 MySQLの場合 数列を生成する機能があります(generate_seriesなど) または事前入力された数値テーブルCROSS JOINは必要ありません 。

    SUBSTRING_INDEX




    1. BLOBを除くすべてのフィールドでSELECTDISTINCTを実行するにはどうすればよいですか?

    2. ResultSetを閉じた後の操作は許可されません(mysql、java)

    3. MySQL-1つのINSERTステートメントにいくつの行を挿入できますか?

    4. レポート内の2つのテーブルからのクエリ