おれのメモ帳_φ(-ω-`*)メモメモ

EC-CUBEの商品並び順の連番を振り直した

EC-CUBE で、商品並び替えがうまくいっていなかったので処理を修正した(2.12.2)。
原因は商品削除時と、商品をカテゴリから取り除いたときの処理で dtb_product_categories がきちんと更新されていないこと。

  • 商品削除時: 余分なレコードが上記テーブルに残ったままになる
  • 商品をカテゴリから取り除いたとき: 上記テーブルが歯抜け状態になる

そのため、商品並び替えをしようとして、上へ、下へ、○番目へ移動、としても、不要なレコードが残っていたり逆に抜けていたりして、狙ったところに移動してくれない。


処理を修正したはいいけど、既におかしくなっているテーブルもきれいにしないといけない。

試行錯誤した結果、以下で並び順を振り直せた。けどもし使う場合は自己責任で。

UPDATE dtb_product_categories
   SET rank = (SELECT COUNT(DISTINCT T.rank)
                 FROM (SELECT * FROM dtb_product_categories) AS T
                WHERE dtb_product_categories.category_id = T.category_id
                  AND dtb_product_categories.rank > T.rank ) + 1;

実は ADMIN_MODE にすると、商品並び替え画面に「内部順位再割り当て」のボタンが出てきて、似たようなことができるみたいだけど、使わなかった。理由は

  • ADMIN_MODE にするとフロント画面にデバッグ表示が出てきちゃうから本番環境で使えない
  • 選んでるカテゴリだけが対象なので、全カテゴリやるのは大変
  • ローカルで試してみたら MySQL では動かなかった(参考サイトのエラーが出た)

上記SQLと「内部順位再割り当て」のSQLは大体同じだけど、再割り当てSQLのOR句でなにしてるかよく分からなかった。上のSQLだとOR句を入れてないので、何かしら考慮漏れがある可能性がある。

あと、カテゴリ内商品数の集計もしなおさないといけないけど、適当に商品情報を更新しておけば再集計されるはず。


【2013/04/19追記】
やっぱり漏れがあった。上記SQLだと連番の隙間は埋めるけど、残ってるゴミレコードがそのままになっている。

なので、一旦以下のSQLで余計なレコードを削除してから、上記SQLで隙間を埋めるのがよい。

DELETE FROM dtb_product_categories
 WHERE product_id IN (
           SELECT cat.product_id
             FROM (SELECT * FROM dtb_product_categories) AS cat,
                  dtb_products AS prd
            WHERE cat.product_id = prd.product_id
              AND prd.del_flg = 1
           );

一応、上記2つのSQLを実行する前にはバックアップを取っておく。

$ mysqldump -u root -p データベース名 dtb_product_categories > dtb_product_categories.sql

問題があったら、以下で戻す。

$ mysql -u root -p データベース名 < dtb_product_categories.sql