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

カンマ区切りの列値を行に分割(展開)します

    更新 このようにSQLでそれを行うことができます

    INSERT INTO branch_table (id, branch_id)
    SELECT e.id, SUBSTRING_INDEX(SUBSTRING_INDEX(e.branch_ids, ',', n.n), ',', -1) branch_id
      FROM eligibility_table e 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
        ORDER BY n
    ) n
     WHERE n.n <= 1 + (LENGTH(e.branch_ids) - LENGTH(REPLACE(e.branch_ids, ',', '')))
     ORDER BY id, branch_id
    
    • エイリアスがnのサブクエリは、 UNION ALL を使用して、この特定のケースでは1から100までの一連の数値(数値または集計テーブル)をオンザフライで生成します。 およびCROSSJOIN データベースに実際の集計テーブルがあると便利な場合があります
    • 外側で最も内側の SUBSTRING_INDEX() リスト内のn番目の要素と外部のSUBSTRING_INDEX()までのすべてを取得します 最後の区切り文字の直後のほとんどの部分を抽出して、n番目の要素自体を効果的に取得します。
    • CROSS JOIN デカルト積である行のセットを生成できます(nに100行、eligibility_tableにすべての行)
    • WHEREの状態 句は、結果セットから不要な行をすべて除外します

    注:このクエリは最大100のブランチIDを分割します。多かれ少なかれ必要な場合は、内部サブクエリを編集して制限を調整できます

    結果はbranch_table:

    | ID | BRANCH_ID |
    ------------------
    |  1 |       621 |
    |  1 |       622 |
    |  1 |       623 |
    |  1 |       625 |
    |  2 |       621 |
    |  2 |       650 |
    

    これがSQLFiddle です。 デモ



    1. データベースの問題に挿入...(不正な文字コーディング)PHP / MYSQL

    2. SQLで列と行を転置する簡単な方法は?

    3. Mysqlトランザクション:コミットとロールバック

    4. PostgreSQLでクエリを実行するために二重引用符を省略します