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

重複を無視して複数の行で2つの列をマージします-MySQL

    テーブルの名前がexampleであると仮定すると、このステートメントでそれを行うことができます(いいえ、見栄えがよくありません)。 :

    UPDATE
        example e1
    SET
        e1.type_a = (
            SELECT
                CONCAT('*', GROUP_CONCAT(DISTINCT n1.value ORDER BY n1.value SEPARATOR '*'), '*') as type_a
            FROM ( 
                SELECT
                    id, 
                CASE 
                    WHEN SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1) = '' THEN NULL
                    ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1)
                END value
                FROM example e CROSS JOIN (
                    SELECT 
                        a.N + b.N * 10 + 1 AS 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.type_a) - LENGTH(REPLACE(e.type_a, '*', '')))
                UNION
                SELECT
                    id, 
                CASE 
                    WHEN SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_b), '*', n.n), '*', -1) = '' THEN NULL
                    ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_b), '*', n.n), '*', -1)
                END value
                FROM example e CROSS JOIN (
                    SELECT 
                        a.N + b.N * 10 + 1 AS 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.type_b) - LENGTH(REPLACE(e.type_b, '*', '')))
            ) n1
            WHERE 
                n1.id = e1.id
            GROUP BY 
                id
        ),
        e1.type_b = ''
    ;
    

    デモ SELECTステートメントの

    説明

    基本的に、メソッド を採用しました peterm の 分割を実行します。外側の*を削除する必要がありました 最初はTRIMによる。

    空の文字列を列の値として許可するために、CASE構造を追加して、そのような値を削除しました。代わりに列の値がNULLの場合は、CASEを

    に置き換えることができます。
    SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1)
    

    および

    SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1)
    

    この構成のUNION(ALLキーワードなし)は、個別の色の値のリストを提供し、GROUP BY idとGROUP_CONCATを使用すると、*分離された値のリストを取得します。最後に、先頭と末尾の*を追加します 要件に合わせて。

    更新の場合、selectを変更して、1つの行(where句を含む)を含む1つの列のみを返すようにする必要があります。

    petermが述べているように、これにより、値リストに最大100個の値が許可されます。これ以上必要になるとは思いませんが、必要な場合は、必要に応じて数値の生成を調整する必要があります。




    1. ブールパラメータをOracleプロシージャC#に渡す方法

    2. PHPを使用してMySQLデータベースから画像を読み取る方法は?

    3. 教義2-フロートの小数点以下2桁?

    4. パラメータ化されたクエリの例