これは簡単な PHP スクリプトで実行できますが、私はデータベースがそれを単独で処理できるようにするという考えが気に入っています。
巧妙なUPDATE
結合を使用してこれを行うこともできますが、テストできないため、代わりに一時テーブルを使用します。Name
アイデアは、カウント > 1 を持つすべての値を選択し、それらに行番号を一時テーブルに割り当てることです。次に、更新結合を使用して、元のテーブルの GroupID を変更します。
SET @rownum=0;
CREATE TEMPORARY TABLE groupnums (groupid INT, Name VARCHAR(16), numgroups INT)
SELECT
@rownum := @rownum + 1 AS groupid,
Name,
COUNT(*) AS numgroups
FROM original_table
GROUP BY Name
HAVING COUNT(*) > 1
UPDATE
original_table
JOIN groupnums ON original_table.Name = groupnums.Name
SET original_table.GroupID = groupnums.groupid
次に、残りのものを0に設定します
UPDATE original_table SET GroupID='0' WHERE GroupID IS NULL
そして、一時テーブルを取り除きます。
DROP TABLE groupnums;
アップデート:
これを自分で簡単にテストしたところ、動作しますが、 の増分値を直接取得できないことがわかりましたgroupid
。は@rownum
各グループではなく行ごとに増分されるため、次のようなグループになり、その間にギャップがあります。
/* Sample results - groups work, but have gaps between GroupID */
Name GroupID etc...
ABC 1
ABC 1
DEF 3
DEF 3
DEF 3
KKK 0
LLL 0
III 6
III 6
更新 2 私はこれを少し複雑にしました。
深く考えると、@rownum
はまったく必要ありません。一時テーブルで自動インクリメント ID を使用するだけです。GroupID
これにより、その間にギャップがなくてもインクリメンタルが生成されます。上記と同じUPDATE
ステートメントを使用して、これに対して結合します。
CREATE TEMPORARY TABLE groupnums (groupid INT NOT NULL AUTO_INCREMENT, Name VARCHAR(16), numgroups INT)
SELECT
NULL AS groupid
Name,
COUNT(*) AS numgroups
FROM original_table
GROUP BY Name
HAVING COUNT(*) > 1