SQLの書き方、考え方についてアドバイスをください。


[テーブル]

カテゴリ(親子関係になっている、今のところ5段階程度)

-category_id
-parent_id(親子関係のキー)
-name

商品

-id
-category_id
-name

2つのテーブルがこのように繋がっており、カテゴリは入れ子になっています。
この状態で特定のカテゴリを削除する場合、サブカテゴリ、カテゴリに属する商品を一括で削除します。

最初に選んだ削除対象のcategory_idをキーに何回もSQLを発行して、
サブカテゴリと商品を下りながら削除するというのがうまいやり方なのでしょうか?

何か参考になるページ、情報などを頂けると助かります。
よろしくお願いします。

回答の条件
  • 1人5回まで
  • 登録:2008/01/31 21:32:17
  • 終了:2008/02/05 09:22:17

ベストアンサー

id:KUROX No.2

KUROX回答回数3542ベストアンサー獲得回数1402008/02/01 10:51:14

ポイント60pt

>最初に選んだ削除対象のcategory_idをキーに何回もSQLを発行して、

>サブカテゴリと商品を下りながら削除するというのがうまいやり方なのでしょうか?

基本的にはYESで問題ない処理だと思います。

速度的に問題なくて、トランザクションが保障されるのなら問題ないと思います。

------

他、考えられるのは

DELETE テーブル名 WHERE category_id EXISTS (select category_id ・・・・)

で、SQLでカテゴリーの一覧を複問い合わせ等を使って簡単に取得できるのなら

そういう方向で・・。

DELETE テーブル名 WHERE category_id IN ('001','012'・・・・)

カテゴリー一覧を配列かなにかに蓄えておいて、それをIN句で展開して削除するとか

たぶん、カテゴリに親子関係があるので、何回も同じカテゴリIDで削除するのが無駄だと

考えるのなら、こういう方向で・・。IN句が使えない場合でも、配列に蓄えて

重複キーで削除しないようにするのなら、速度的に早くはなると思います。

-----

メリットがないのなら、質問文に書いてある方法を私はお勧めします。

id:southgate_01

ありがとうございます、大変参考になります。

削除部分はこのやり方でやろうと思います。

2008/02/01 12:26:42

その他の回答(1件)

id:memo77 No.1

memo77回答回数238ベストアンサー獲得回数202008/01/31 22:10:59

ポイント35pt

環境がわからないのですが、ごく最近のDBには階層問い合わせと言う機能があります。

http://q.hatena.ne.jp/1182220220


階層問い合わせがないなら、例えばSQLServerなら下記のような感じでできますね。


CREATE TABLE #delid(category_id int,PRIMARY KEY(category_id))


INSERT INTO #delid (category_id)

SELECT category_id

FROM t_category

WHERE parent_id = @delete_id


WHILE @@ROWCOUNT>0

BEGIN

INSERT INTO #delid

SELECT T1.category_id

FROM t_category AS T1

INNER JOIN #delid AS T2

ON T1.category_id=T2.parent_id

LEFT OUTER JOIN #delid AS T3

ON T1.category_id=T3.category_id

WHERE T3.category_id IS NULL

GROUP BY T1.category_id

END


DELETE T1

FROM t_shohin AS T1

INNER JOIN #delod AS T2

ON T1.category_id=T2.category_id

id:southgate_01

ご丁寧な解答をいただき、ありがとうございます。

なにぶん、サンデープログラマーなのでアドバイスいただいた内容を理解来ません、申し訳ないです。

データベースはMySQLを利用しているのですが、

http://www.mysql.gr.jp/mysqlml/mysql/msg/12071

アドバイスのおかげで参考になりそうなところを見つけることが出来ましたので、頑張ってみます。

2008/02/01 00:24:34
id:KUROX No.2

KUROX回答回数3542ベストアンサー獲得回数1402008/02/01 10:51:14ここでベストアンサー

ポイント60pt

>最初に選んだ削除対象のcategory_idをキーに何回もSQLを発行して、

>サブカテゴリと商品を下りながら削除するというのがうまいやり方なのでしょうか?

基本的にはYESで問題ない処理だと思います。

速度的に問題なくて、トランザクションが保障されるのなら問題ないと思います。

------

他、考えられるのは

DELETE テーブル名 WHERE category_id EXISTS (select category_id ・・・・)

で、SQLでカテゴリーの一覧を複問い合わせ等を使って簡単に取得できるのなら

そういう方向で・・。

DELETE テーブル名 WHERE category_id IN ('001','012'・・・・)

カテゴリー一覧を配列かなにかに蓄えておいて、それをIN句で展開して削除するとか

たぶん、カテゴリに親子関係があるので、何回も同じカテゴリIDで削除するのが無駄だと

考えるのなら、こういう方向で・・。IN句が使えない場合でも、配列に蓄えて

重複キーで削除しないようにするのなら、速度的に早くはなると思います。

-----

メリットがないのなら、質問文に書いてある方法を私はお勧めします。

id:southgate_01

ありがとうございます、大変参考になります。

削除部分はこのやり方でやろうと思います。

2008/02/01 12:26:42
  • id:southgate_01
    southgate_01 2008/02/01 12:36:26
    どなたか、ずばりSQLを書いていただけませんか?
    私自身は難易度がまったく分かっていないので失礼な質問でしたらすいません。
    データベースはMySQLです。

    [テーブル]

    id(主キー)
    parent_id(親)
    name(カテゴリ名)

    [データ]

    id 1
    parent_id null
    name 書籍

    id 2
    parent_id 1
    name 専門書

    id 3
    parent_id 2
    name プログラム言語

    id 4
    parent_id 3
    name PHP

    このようなテーブル構成なのですが、id=2が指定された場合、その子カテゴリである、
    「プログラム言語」「PHP」のidを取得したいのです。

    「parent_id = 2」からid3を取得して、
    「parent_id = 3」からid4を取得して、
    「parent_id = 4」から、もうないや・・・

    とやる以外の方法がありそうなんですが、いろいろ調べたのですが理解できませんでした。
  • id:KUROX
    自己結合か、JOINを使うと思います。

    http://sasuke.main.jp/zikoketugou.html
  • id:southgate_01
    southgate_01 2008/02/01 20:37:34
    ありがとうございます、参考になります。
    まだ出来てないのですが、出来そうな雰囲気はあります。。。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません