Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL-存在还是全部?_Sql_Sql Server - Fatal编程技术网

SQL-存在还是全部?

SQL-存在还是全部?,sql,sql-server,Sql,Sql Server,我有两个不同的表和学生成绩; 成绩表有一个属性student\u id,该属性引用student表中的student\u id。 我如何找到哪个学生拥有所有的成绩 如果不清楚, Student ID Name 1 1 John 2 2 Paul 3 3 George 4 4 Mike 5 5 Li

我有两个不同的表和学生成绩; 成绩表有一个属性student\u id,该属性引用student表中的student\u id。 我如何找到哪个学生拥有所有的成绩

如果不清楚,

Student     ID     Name
   1         1       John        
   2         2       Paul
   3         3       George
   4         4       Mike
   5         5       Lisa

Grade     Student_Id   Course   Grade
   1          1         Math       A
   2          1         English    B
   3          1         Physics    C
   4          2         Math       A
   5          2         English    A
   6          2         Physics    B
   7          3         Economics  A
   8          4         Art        C
   9          5         Biology    A

Assume there is only grade a,b,c (no d, e or fail) 
我只想找约翰,因为他有a、b、c三个等级 像保罗(2)这样的其他学生不应该被选中,因为他没有c级。不管他选哪门课,我只需要看看他是否有所有的分数

感觉我应该像sql中的exist或all函数一样,但不确定。
请帮忙。提前谢谢。

您可以使用
HAVING COUNT(DISTINCT Grade)=3
检查学生是否拥有所有3个年级:

SELECT Name
FROM Student S
JOIN Grade G ON S.ID = G.Student_Id
GROUP BY Name
HAVING COUNT(DISTINCT Grade) = 3
猜测连接上的
S.ID
vs
S.Student
。不确定有什么区别。

使用exists

 select * from student s
  where exists ( select 1
                       from grades g where g.Student_Id=s.ID 
                        group by g.Student_Id
                        having count(distinct Grade)=3
               )  
范例

with Student as
(
select 1 as  id,'John' as person
union all
select 2 as  id,'Paul' as person
union all
select 3 as  id,'jorge'
),
Grades as
(
select 1 as Graden, 1 as Student_Id, 'Math' as Course, 'A' as Grade
union all
select 2 as Graden, 1 as Student_Id, 'English' as Course, 'B' as Grade 
union all
select 3 as Graden, 1 as Student_Id, 'Physics' as Course, 'C' as Grade
union all
select 4 as Graden, 2 as Student_Id, 'Math' as Course, 'A' as Grade 
union all
select 5 as Graden, 2 as Student_Id, 'English' as Course, 'A' as Grade 
union all
select 6 as Graden, 2 as Student_Id, 'Physics' as Course, 'B' as Grade 
)
select * from Student s
  where exists ( select 1
                       from Grades g where g.Student_Id=s.ID 
                        group by g.Student_Id
                        having count(distinct Grade)=3
               )

拥有计数(不同等级)=3
我使用它,因为在您的样本数据中等级类型为3

我将使用
分组依据
拥有
,但如下所示:

SELECT s.Name
FROM Student s JOIN
     Grade g
     ON s.ID = g.Student_Id
GROUP BY s.id, s.Name
HAVING COUNT(DISTINCT g.Grade) = (SELECT COUNT(DISTINCT g2.grade) FROM grade g2);
create table Grade
(
    Code char(1) not null constraint PK_Grade primary key clustered
)

insert Grade (Code) values ('A'),('B'),('C')

create table Course
(
    Id bigint not null identity(1,1) constraint PK_Course primary key clustered
    , Name nvarchar(128) not null constraint UK_Course_Name unique  
)

insert Course (Name) values ('Math'),('English'),('Physics'),('Economics'),('Art'),('Biology')

create table Student
(
    Id bigint not null identity(1,1) constraint PK_Student primary key clustered
    ,Name nvarchar(128) not null constraint UK_Student_Name unique  
)

set identity_insert Student on --inserting with IDs to ensure the ids of these students match data from your question

insert Student (Id, Name)
values (1, 'John')        
    ,  (2, 'Paul')
    ,  (3, 'George')
    ,  (4, 'Mike')
    ,  (5, 'Lisa')

set identity_insert Student off

create table StudentCourse
(
    Id bigint not null identity(1,1) constraint PK_StudentCourse primary key
    , StudentId bigint not null constraint FK_StudentCourse_StudentId foreign key references Student(Id)
    , CourseId bigint not null constraint FK_StudentCourse_CourseId foreign key references Course(Id)
    , Grade char /* allow null in case we use this table for pre-results; otherwise make non-null */ constraint FK_StudentCourse_Grade foreign key references Grade(Code)
    , Constraint UK_StudentCourse_StudentAndCourse unique clustered (StudentId, CourseId)
)

insert StudentCourse (StudentId, CourseId, Grade)
select s.Id, c.Id, x.Grade
from (values
   ('John',       'Math',     'A')
  ,('John',       'English',  'B')
  ,('John',       'Physics',  'C')
  ,('Paul',       'Math',     'A')
  ,('Paul',       'English',  'A')
  ,('Paul',       'Physics',  'B')
  ,('George',     'Economics','A')
  ,('Mike',       'Art',      'C')
  ,('Lisa',       'Biology',  'A')
) x(Student, Course, Grade)
inner join Student s on s.Name = x.Student
inner join Course c on c.Name = x.Course

你说“所有的分数都在那里”,所以查询不应该使用常数。在深入研究答案之前,这里有一个练习,这样你就可以看到这个练习了

正如Gordon Linoff在他的文章中指出的那样,您应该使用
GroupBy
Having Count(Distinct…)

但是,我建议更改您的设计,以确保每个问题都有表。
目前,您的
成绩表包含每个学生每门课程的成绩。因此,它更像是一个
StudentCourse
表(也就是说,学生和课程的组合是唯一的/为您提供了该表的自然键)。你应该有一个实际的
成绩
表来列出可用的成绩;e、 g

create table Grade
(
    Code char(1) not null constraint PK_Grade primary key clustered
)

insert Grade (Code) values ('A'),('B'),('C')
这样,如果您决定包含D和E级,您就可以确保查询仍然有效,而无需修改任何代码。它还确保您只需查询一个小表即可获得完整的成绩列表,而不是一个潜在的大表;所以会有更好的表现。最后,它还将帮助您维护良好的数据;i、 这样你就不会因为打字错误而意外地和X年级的学生在一起;i、 e.由于数据库中存在验证/约束

select Name from Student s
where s.Id in 
(
    select sc.StudentId
    from StudentCourse sc
    group by sc.StudentId
    having count(distinct sc.Grade) = (select count(Code) from Grade)
)
order by s.Name
同样,创建课程表也是明智的。在这种情况下,持有每个课程的ID;因为在StudentCourse表中保留完整的课程名称(我们现在称之为)会占用更多的空间,并且同样缺乏验证/约束。因此,我建议修改您的数据库模式,如下所示:

SELECT s.Name
FROM Student s JOIN
     Grade g
     ON s.ID = g.Student_Id
GROUP BY s.id, s.Name
HAVING COUNT(DISTINCT g.Grade) = (SELECT COUNT(DISTINCT g2.grade) FROM grade g2);
create table Grade
(
    Code char(1) not null constraint PK_Grade primary key clustered
)

insert Grade (Code) values ('A'),('B'),('C')

create table Course
(
    Id bigint not null identity(1,1) constraint PK_Course primary key clustered
    , Name nvarchar(128) not null constraint UK_Course_Name unique  
)

insert Course (Name) values ('Math'),('English'),('Physics'),('Economics'),('Art'),('Biology')

create table Student
(
    Id bigint not null identity(1,1) constraint PK_Student primary key clustered
    ,Name nvarchar(128) not null constraint UK_Student_Name unique  
)

set identity_insert Student on --inserting with IDs to ensure the ids of these students match data from your question

insert Student (Id, Name)
values (1, 'John')        
    ,  (2, 'Paul')
    ,  (3, 'George')
    ,  (4, 'Mike')
    ,  (5, 'Lisa')

set identity_insert Student off

create table StudentCourse
(
    Id bigint not null identity(1,1) constraint PK_StudentCourse primary key
    , StudentId bigint not null constraint FK_StudentCourse_StudentId foreign key references Student(Id)
    , CourseId bigint not null constraint FK_StudentCourse_CourseId foreign key references Course(Id)
    , Grade char /* allow null in case we use this table for pre-results; otherwise make non-null */ constraint FK_StudentCourse_Grade foreign key references Grade(Code)
    , Constraint UK_StudentCourse_StudentAndCourse unique clustered (StudentId, CourseId)
)

insert StudentCourse (StudentId, CourseId, Grade)
select s.Id, c.Id, x.Grade
from (values
   ('John',       'Math',     'A')
  ,('John',       'English',  'B')
  ,('John',       'Physics',  'C')
  ,('Paul',       'Math',     'A')
  ,('Paul',       'English',  'A')
  ,('Paul',       'Physics',  'B')
  ,('George',     'Economics','A')
  ,('Mike',       'Art',      'C')
  ,('Lisa',       'Biology',  'A')
) x(Student, Course, Grade)
inner join Student s on s.Name = x.Student
inner join Course c on c.Name = x.Course

用您正在使用的数据库管理系统(如SQL Server、Oracle、MySQL等)标记您的问题,
grade
表中的第一列是否应为
GradeID
?现在有两个“等级”栏。。。