2012-03-29 11 views
3

У меня есть база данных MySQL в стиле иерархии. Существует 4 таблицы под названием pages, regions, elements и content. Страницы находятся наверху, а контент внизу.MySQL удаляет все «дочерние» элементы в иерархии

Для упрощения:

страницы имеет столбец:

id 

регионы имеет столбцы:

id 
page_id 

элементы имеет столбцы:

id 
region_id 

содержание имеет столбцы:

id 
element_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

Использование 'ON 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

Если вы создали таблицу при удалении каскада при создании таблиц, он должен был удалить все. Но если вы не удаляете каскад, вам нужно создать четыре разных оператора удаления. Харго опубликовал свой ответ за несколько секунд до моего, но да, его ответ почти такой же, как у меня. – Churk

+1

На самом деле, если у вас есть удаление на каскаде, все, что вам нужно сделать, это удалить страницы, где pages.id = 1; и оставшаяся таблица удалила бы их строки. Если вам нужно настраивать таблицы с помощью каскада delete, вот ссылка: http://www.java2s.com/Tutorial/MySQL/0080__Table/FOREIGNKEYONDELETECASCADEONUPDATECASCADE.htm – Churk

0

Inner присоединиться может быть более эффективным, чем несколько вложенных подзапросов, попробуйте это

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

Смежные вопросы