2012-03-29 10 views
3

階層構造でMySQLデータベースをセットアップしました。 pages,regionselements、およびcontentという4つのテーブルがあります。ページは上部にあり、コンテンツは下部にあります。MySQLが階層内のすべての「子」要素を削除します

を簡単にするために:カラム有する

ページ:

id 
page_id 

素子列を有する

id 

領域は列を有する

id 
region_id 

コンテンツの列があります。私はちょうどページのidを使用してページのすべての子を削除できるようにしたい

id 
element_id 

これまでは、ページのIDを使用して下部のコンテンツを選択するためにネストされたselectステートメントを使用できましたが、要素、リージョン、またはページは選択されませんでした。

SELECT * FROM `content` WHERE `element_id` IN (
    SELECT `id` FROM `elements` WHERE `region_id` IN (
     SELECT `id` FROM `regions` WHERE `page_id` IN (
      SELECT `id` FROM `pages` WHERE `id` = 1 
     ) 
    ) 
) 

とにかくこれを効率的に行うには?ありがとう。


@Hagoと@Churkのおかげで、ここで私の最終的な解決策(基本的にChurkのコード、修正ほんの少し)です:

DELETE `content`, `elements`, `regions` FROM `content` 
JOIN `elements` ON `elements`.`id` = `content`.`element_id` 
JOIN `regions` ON `regions`.`id` = `elements`.`region_id` 
JOIN `pages` ON `pages`.`id` = `regions`.`page_id` 
WHERE `pages`.`id` = 1 
+2

DELETE CASCADE'上で使用する ' – zerkms

答えて

3
DELETE FROM content 
JOIN elements ON elements.id = content.element_id 
JOIN regions ON regions.id = elements.region_id 
JOIN pages ON pages.id = regions.page_id 
WHERE pages.id = 1 
+0

テーブルを作成したときに削除カスケード時にテーブルを設定すると、すべてが削除されているはずです。しかし、カスケードで削除がない場合は、4つの異なるdelete文を作成する必要があります。 Hargoは私の前に彼の答えの秒を掲示したが、はい彼の答えは私のものとほとんど同じです。 – Churk

+1

実際にカスケードで削除がある場合は、pages.id = 1のページを削除するだけです。残りのテーブルは行が削除されていました。削除カスケードを使用してテーブルを設定する必要がある場合は、ここに参考ハウトがあります。http://www.java2s.com/Tutorial/MySQL/0080__Table/FOREIGNKEYONDELETECASCADEONUPDATECASCADE.htm – Churk

0

内部結合は、複数のネストされたサブクエリよりも効率的である可能性があり、これを試してみてください

select 
    c.id 
from 
    contents as c 
inner join 
    elements as e on c.element_id = e.id 
inner join 
    regions as r on e.region_id = r.id 
where 
    r.page_id = 1 
+0

おかげで、それはおそらく私の最初のクエリよりも効率的です。しかし、子データだけでなく、すべてのデータを選択する(そして、もちろん削除することができる)という問題を解決することはできません。 – Coolist

関連する問題