0 レビュー
1 回答
関連するエントリを処理するためのPHP/MySQLコード
テーブルがあります:
Name GroupID etc...
ABC
ABC
DEF
DEF
DEF
KKK
LLL
III
III
PHP / MYSQLミックスをこれに処理したい:
Name GroupID etc...
ABC 1
ABC 1
DEF 2
DEF 2
DEF 2
KKK 0
LLL 0
III 3
III 3
すなわち。行に重複した名前のエントリが存在する場合(文字列が完全に一致する場合)、その名前のすべてのエントリにGroupID(自動的にインクリメント)が割り当てられます。エントリが一意の名前の場合、GroupIDに0が割り当てられます
私のテーブルには250,000のエントリがありますが、これを達成するための最速の方法は何ですか?動作するコードは素晴らしいですが、高レベルのアルゴリズムで十分です。
ありがとう!
わからない
0
レビュー
答え :
解決策:
これは簡単なPHPスクリプトで実行できますが、データベースに単独で処理させるというアイデアが気に入っています。
これは賢いUPDATE
結合で行うことができますが、テストできないため、代わりに一時テーブルを使用します。アイデアは、カウントが1より大きい Name
のすべての値を選択し、それらに行番号を一時テーブルに割り当てることです。次に、更新結合を使用して、元のテーブルのGroupIDを変更します。
SET @rownum = 0;
CREATE TEMPORARY TABLE groupnums(groupid INT、Name VARCHAR(16)、numgroups INT)
選択する
@rownum:= @rownum + 1 AS groupid、
{-コード-2}、
COUNT(*)AS numgroups
FROM original_table
GROUPBY{-コード-2}
HAVING COUNT(*)> 1
{-コード-1}
original_table
groupnumsONoriginal_table。Name=groupnums。Nameに参加します
SEToriginal_table。GroupID=groupnums。groupid
次に、残りを0に設定します
UPDATE original_table SET GroupID = '0' WHERE GroupID IS NULL
そして一時テーブルを取り除きます。
DROP TABLE groupnums;
更新:
これを自分ですばやくテストしたところ、機能していても、 groupid
の増分値を直接取得できないことがわかりました。 @rownum
は、グループごとではなく行ごとにインクリメントされるため、次のようなグループにギャップができてしまいます。
/ *サンプル結果-グループは機能しますが、GroupIDの間にギャップがあります* /
NameGroupIDなど..
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)
選択する
NULLAS{-コード-6}
{-コード-2}、
COUNT(*)AS numgroups
FROM original_table
GROUPBY{-コード-2}
HAVING COUNT(*)> 1
わからない
同様の質問
私たちのウェブサイトで同様の質問で答えを見つけてください。