2016-08-22 1 views
0

У меня есть 3 таблицы, используемой в этом запросе:Можете ли вы улучшить обновление mysql с двумя встроенными выборами с помощью соединений?

  1. инструктора (содержит «мягкий» удален столбец)
  2. школы (содержит «мягкий» удален столбец)
  3. instructor_school (таблицу ассоциации между инструктором и школа)

Если школа помечаются как удаленные, я хочу, чтобы преподаватели этой школы также быть помечены как удаленные, но только если все их школ отмечены как удаленные. Вот мой предложенный запрос:

update instructor as i 
set deleted=1 
where 
(select count(*) from instructor_school as i_s join school s 
on s.id=i_s.school_id 
where i_s.instructor_id=i.id) = 
(select count(*) from instructor_school as i_s join school s 
on s.id=i_s.school_id 
where i_s.instructor_id=i.id and s.deleted=1); 

Если мы только позволили каждому преподавателю, чтобы быть в одной школе, то запрос будет гораздо проще:

UPDATE instructor i 
JOIN instructor_school as i_s ON i_s.instructor_id = i.id 
JOIN school as s on s.id=i_s.school_id 
SET i.deleted = 1 
where s.deleted = 1 

Мой вопрос - это запрос наилучший подход к решить эту проблему - или вы можете предложить лучший запрос?

Спасибо за любые предложения!

ответ

2
UPDATE instructor AS i 
JOIN instructor_school i_s_deleted ON i.id = i_s_deleted.instructor_id 
JOIN school s_deleted ON i_s_deleted.school_id = s_deleted.id AND s_deleted.deleted = 1 
LEFT JOIN instructor_school AS i_s_active 
    JOIN school s_active ON i_s_active.school_id = s_active.id AND s_active.deleted <> 1 
ON i.id = i_s_active.instructor_id 
SET i.deleted=1 
WHERE i_s_active.school_id IS NULL; 

То, что я здесь был первым, я присоединился к instructor_school к и в школу, чтобы убедиться, что есть школа, которая будет удалена. Затем я ушел, снова присоединившись к trainor_school и школе, а затем положил туда, где i_s_active.school_id имеет значение null в my where where. Это обеспечит, чтобы преподаватель не был связан с какой-либо активной школой.

Надеюсь, это поможет!

+0

Большое спасибо! Это намного чище и, по-видимому, более эффективно. Я буду использовать его вместо предложенного выше запроса. –

+0

Не должно ли положение on для левого соединения для trainor_school быть в конце этой строки и до соединения для s_active? Кроме того, a) не должно быть никаких строк в таблице ассоциации с одним столбцом как null, и b) если преподаватель связан с не удаленной школой, то мы не хотим, чтобы он был помечен как удаленный. Неужели я не понимаю ваш ответ? –

+0

1) Я использовал ОБЪЕДИНЕНИЕ В ЛЕВОЙ ВСТУПЛЕНИИ - потому что я хочу ЛЕВОЕ ПРИСОЕДИНЯТЬСЯ к инструкторским школам, чтобы я не исключил никаких инструкторов, но я хочу сделать INNER JOIN в школу, потому что я хочу вернуть ТОЛЬКО школы, которые вернется с моего ВЛЕВОГО ПРИСОЕДИНЕНИЯ к инструкторским школам. Если вы хотите переключить это, вам придется изменить JOIN в школу (s_active) на LEFT JOIN. 2) a) Я не понимаю этот вопрос. b) Это именно то, что мы делаем, введя ЛЕВЫЙ ПРИСОЕДИНЯЙТЕСЬ С ВНУТРЕННЕМ ПРИСОЕДИНЕНИЕМ в активные школы, где i_s.active IS NULL. – user6655061