web-dev-qa-db-ja.com

SQL分割コンマ区切り行

可変数のコンマ区切り値を持つ列があります:

somethingA,somethingB,somethingC
somethingElseA, somethingElseB

そして、結果に各値を取り、行を作成する必要があります。

somethingA
somethingB
somethingC
somethingElseA
somethingElseB

SQL(MySQL)でこれを行うにはどうすればよいですか?

(私は「内破」と「側面図」をグーグルで試しましたが、関連する質問は表示されないようです。関連するすべてのSO質問はもっと複雑なことをしようとしています)

20
Don P

このような純粋なSQLでそれを行うことができます

_SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(t.values, ',', n.n), ',', -1) value
  FROM table1 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
    ORDER BY n
) n
 WHERE n.n <= 1 + (LENGTH(t.values) - LENGTH(REPLACE(t.values, ',', '')))
 ORDER BY value
_

注:トリックは、tally(numbers)テーブルと非常に便利なこの場合MySQL関数を活用することです SUBSTRING_INDEX() 。このようなクエリを多数実行する(分割する)場合、この例のようにサブクエリでオンザフライで生成するのではなく、永続化された集計テーブルを作成して使用することを検討できます。この例のサブクエリは、1〜100の数字のシーケンスを生成し、ソーステーブルの行ごとに最大100個の区切り値を効果的に分割できます。多少必要な場合は、簡単に調整できます。

出力:

 |値| 
 | ------------- | somethingA | 
 | somethingB | 
 | somethingC | 
 | somethingElseA | 
 | somethingElseB | 

ここに---(SQLFiddleデモ


これは、クエリが永続的な集計テーブルでどのように見えるかです

_SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(t.values, ',', n.n), ',', -1) value
  FROM table1 t CROSS JOIN tally n
 WHERE n.n <= 1 + (LENGTH(t.values) - LENGTH(REPLACE(t.values, ',', '')))
 ORDER BY value
_

ここにSQLFiddleデモ

64
peterm