Удаление записей из одной таблицы, если все записи равны определенному значению

#sql #oracle #plsql #subquery #sql-delete

#sql #Oracle #plsql #подзапрос #sql-удалить

Вопрос:

Таблица учащихся

 Student_ID  School          Home State  Grade      Age
85          Washington St   Colorado    Junior     22
90          Washington St   Washington  Senior     23
81          Oregon          California  Junior     21
21          Washington      Washington  Sophomore  21
  

Таблица посещаемости

 Student_ID  Active  Date
85          N       9/22/20
85          N       9/21/20
81          Y       9/22/20
81          N       9/21/20
  

Привет, в Oracle DB, если я хочу очистить таблицу с информацией об ученике, посмотрев, кто все еще является активным учеником. Путем сортировки по Student_ID в таблице посещаемости я хочу найти студентов, если у них есть все значения, для которых active = ‘N’ . Если все значения для каждого учащегося активны = ‘N’, то я знаю, что они больше не являются учащимися, я хотел бы удалить записи из таблицы Student (student 85). Однако, если только в записях для каждого учащегося есть Active = ‘Y’, тогда я ничего не буду удалять с этим учащимся, поскольку я знаю, что они все еще активны (учащийся 81). Каков наилучший способ сделать это, я пытался использовать оператор all, но мне не удалось получить желаемые результаты. Ниже приведен запрос, который я пытался использовать.

 DELETE /*  parallel (a) */ FROM STUDENT a 
WHERE ( a.student_ID  = ALL
(SELECT /*  parallel (b) */ b.student_id, b.active FROM attendance b WHERE b.active = 'N')); 
  

Ответ №1:

Один из вариантов использует not exists :

 delete from student s
where not exists (
    select 1 from attendance a where a.student_id = s.student_id and a.active = 'Y'
)
  

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

 delete from student s
where (
    select min(active) from attendance a where a.student_id = s.student_id
) = 'N'
  

Ответ №2:

Вы можете проверить наличие строк ‘Y’ с помощью агрегации:

 DELETE 
FROM STUDENT
WHERE student_ID IN
 (
   SELECT student_id
   FROM attendance
   GROUP BY student_id
   HAVING MAX(active) = 'N' -- no Y for this student
 ); 
  

Ответ №3:

 NOT Exists 
  

здесь будет лучшим вариантом, поскольку, как я предполагаю, вам нужно обрабатывать несколько огромных таблиц.
Я повторяю 1-й запрос GMB.