Возвращает student_ids где хотя бы один из каждой категории - PullRequest
0 голосов
/ 15 февраля 2019

Скажем, у нас есть три таблицы учеников, задания и предметы.Я хочу вернуть все student_ids, где этот студент выполнил хотя бы одно задание по каждому предмету, который имеет ученик с именем first_name = 'place' и last_name = 'holder'.

Таблица ученика:

Student_id | first_name | last_name
------------------------------------
     1     |   place    | holder
     2     |            |           
     3     |            |

Предметы:

subject_id | name
-----------------
     1     | Math
     2     | English
     3     | Science

Назначения:

student_id | subject_id
-----------------------
     1     |    1
     1     |    2
     1     |    3
     2     |    1
     2     |    2
     2     |    3
     3     |    1
     3     |    2

Итак, в этом случае я бы хотел, чтобы результаты моего запроса были:

student_id
----------
     1
     2

I 'Мы пробовали несколько разных методов, таких как использование операций над множествами и тому подобное, но ни один из них, похоже, не дает абсолютно правильных результатов.Я продолжаю получать всех студентов, которые выполнили хотя бы одно задание по ЛЮБОМУ предмету, в котором ученик-заполнитель выполнил задание.

Ответы [ 3 ]

0 голосов
/ 15 февраля 2019

Соединение двух таблиц Subjects и Assignments достаточно.Вам необходимо достичь количества предметов для желаемых студентов.

with Subjects( subject_id, name) as
(
 select 1,'Math'    from dual union all
 select 2,'English' from dual union all
 select 3,'Science' from dual
),   
     Assignments( student_id, subject_id) as
(     
 select 1,1 from dual union all
 select 1,2 from dual union all 
 select 1,3 from dual union all
 select 2,1 from dual union all
 select 2,2 from dual union all
 select 2,3 from dual union all
 select 3,1 from dual union all
 select 3,2 from dual
)
select student_id
  from ( select count(distinct subject_id) as subject_id from Subjects ) s
  join Assignments a on a.subject_id = s.subject_id 

student_id
----------
1
2 
0 голосов
/ 25 июня 2019

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

--this will get a 'standard' list of subjects 
--(with at least one completed assignment by the 'standard' student)
--to which all students will be compared
select distinct subject_id
from assignments a
inner join students s
on s.student_id = a.student_id
where s.first_name = 'place'
and s.last_name = 'holder';


--cross join the students and the list above 
--we will outer join this to the assigments table later
select students.student_id as std_student, standard_subjects.subject_id as std_subj
from students, 
(select distinct subject_id
from assignments a
inner join students s
on s.student_id = a.student_id
where s.first_name = 'place'
and s.last_name = 'holder') standard_subjects;


--outer join this to a set of completions 
--to compare actual completions to 
--the standard set by the 'placeholder' student
with completions as (select student_id, subject_id 
from assignments
group by student_id, subject_id
) 
select std_student, std_subj, student_id
from (select students.student_id as std_student, standard_subjects.subject_id as std_subj
from students, 
(select distinct subject_id
from assignments a
inner join students s
on s.student_id = a.student_id
where s.first_name = 'place'
and s.last_name = 'holder') standard_subjects) standard
left join completions
on standard.std_student = completions.student_id
and standard.std_subj = completions.subject_id;


--sum up the completions and select only the students
--having a completion in each 'standard' subject
select std_student as result 
from (
with completions as (select student_id, subject_id 
from assignments
group by student_id, subject_id
) 
select std_student, std_subj, student_id
from (select students.student_id as std_student, standard_subjects.subject_id as std_subj
from students, 
(select distinct subject_id
from assignments a
inner join students s
on s.student_id = a.student_id
where s.first_name = 'place'
and s.last_name = 'holder') standard_subjects) standard
left join completions
on standard.std_student = completions.student_id
and standard.std_subj = completions.subject_id) comparison
having count(student_id) = count(std_subj)
group by std_student;
0 голосов
/ 15 февраля 2019

Вы можете использовать SQL Join, чтобы получить желаемый результат.Это означает, что для каждого субъекта существует только одно задание:

SELECT students.student_id FROM students
INNER JOIN assignments on assignments.student_id = students.student_id
GROUP BY students.student_id
HAVING COUNT(*) = (SELECT COUNT(*) FROM subjects)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...