我有两张桌子: 考试(StudentID,SubjectID), 受试者(SubjectID)
并希望选择对所有科目进行考试的学生。怎么做? 是否可以不使用GROUP和COUNT?
答案 0 :(得分:2)
你可以通过多种方式实现这一目标。其中之一:
DECLARE @students TABLE ( id INT )
DECLARE @exams TABLE ( id INT )
DECLARE @studentexams TABLE
(
studentid INT ,
examid INT
)
INSERT INTO @exams
VALUES ( 1 ),
( 2 )
INSERT INTO @students
VALUES ( 1 ),
( 2 ),
( 3 )
INSERT INTO @studentexams
VALUES ( 1, 1 ),
( 1, 2 ),
( 2, 1 )
SELECT *
FROM @students s
WHERE NOT EXISTS ( SELECT *
FROM @exams e
WHERE e.id NOT IN ( SELECT se.examid
FROM @studentexams se
WHERE se.studentid = s.id ) )
输出:
id
1
答案 1 :(得分:1)
这是你之后的事情:
--list all students
select *
from @students st
--where there isn't
where not exists
(
--any subject
select top 1 1
from @subjects su
--for which that student did not take an exam
where su.id not in
(
select subjectid
from @exams e
where studentId = st.id
)
)
这里是完整的代码(即包括样本数据表):
declare @subjects table(id bigint not null identity(1,1), title nvarchar(32))
declare @students table(id bigint not null identity(1,1), name nvarchar(32))
declare @exams table(id bigint not null identity(1,1), studentId bigint, subjectId bigint, grade nchar(1), attempt int)
insert @subjects select 'Maths' union select 'English' union select 'Geography' union select 'Computer Science'
insert @students select 'Anna' union select 'Billy' union select 'Christie' union select 'Daniel'
insert @exams select st.Id, su.Id, grade, attempt
from
(
select 'Anna' student, 'Maths' subject, 'A' grade, 1 attempt
union select 'Anna' student, 'English' subject, 'A' grade, 1 attempt
union select 'Anna' student, 'Geography' subject, 'A' grade, 1 attempt
union select 'Anna' student, 'Computer Science' subject, 'A' grade, 1 attempt
union select 'Billy' student, 'Maths' subject, 'A' grade, 1 attempt
union select 'Billy' student, 'Computer Science' subject, 'A' grade, 1 attempt
union select 'Christie' student, 'Maths' subject, 'A' grade, 1 attempt
union select 'Christie' student, 'English' subject, 'F' grade, 1 attempt
union select 'Christie' student, 'English' subject, 'E' grade, 2 attempt
union select 'Christie' student, 'English' subject, 'A' grade, 3 attempt
union select 'Daniel' student, 'Maths' subject, 'A' grade, 1 attempt
union select 'Daniel' student, 'English' subject, 'A' grade, 1 attempt
union select 'Daniel' student, 'Geography' subject, 'A' grade, 1 attempt
union select 'Daniel' student, 'Computer Science' subject, 'F' grade, 1 attempt
union select 'Daniel' student, 'Computer Science' subject, 'A' grade, 2 attempt
) x
inner join @students st on st.name = x.student
inner join @subjects su on su.title = x.subject
--list all students
select *
from @students st
--where there isn't
where not exists
(
--any subject
select top 1 1
from @subjects su
--for which that student did not take an exam
where su.id not in
(
select subjectid
from @exams e
where studentId = st.id
)
)