2012-03-29 116 views
3

我有一个层次结构样式的MySQL数据库设置。有4个表称为pagesregions,elementscontent。页面位于顶部,内容位于底部。MySQL删除层次结构中的所有“子”元素

为了简化:具有柱

的网页:

id 

区域具有列:

id 
page_id 

元件具有列:

id 
region_id 

内容有列:

id 
element_id 

我希望能够删除只使用页的id的所有页面的儿童。

到目前为止,我已经能够使用嵌套的select语句使用页面的ID选择底部内容,但不会选择元素,区域或页面。

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,这里是我的最终解决方案(基本丘尔克古尔马的代码,修改一点点):

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

使用'ON DELETE CASCADE' – zerkms 2012-03-29 01:40:36

回答

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

如果您在创建表时设置了删除级联表,则应删除所有内容。但是,如果您没有级联删除,那么您必须创建四个不同的删除语句。哈哥在我的前几秒发布了他的答案,但是他的答案与我的答案非常相似。 – Churk 2012-03-29 01:55:39

+1

实际上,如果您在级联上删除,您只需删除pages.id = 1的页面;剩下的表格将删除其行。如果您必须能够使用删除级联设置表,请参阅以下参考howto:http://www.java2s.com/Tutorial/MySQL/0080__Table/FOREIGNKEYONDELETECASCADEONUPDATECASCADE.htm – Churk 2012-03-29 01:57:40

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 2012-03-29 01:46:32