关于在mysql中进行子查询的问题

时间:2015-11-10 22:28:05

标签: mysql

首先,这是作业的一部分,但我正在尝试更多地澄清subquerying如何在初始查询方面起作用。

问题是列出在他或她已经完成的所有课程中获得A的每个学生和SSN的名称,即没有Null成绩,并且每个成绩都是A。

我认为这可以通过子查询来完成吗?或者我应该使用一些外部联接方法来组合在所有课程中只有A的学生。我不确定哪个应该是嵌套查询和外部查询。我试过了:

SELECT *
From Student S JOIN Enrollment E
WHERE S.SSN = E.SSN AND E.Grade = "A"
ORDER BY E.CourseNumber

作为我的嵌套查询,它将返回所有有A的学生,但问题是询问哪些学生在所有课程中都获得了A.不知道我会做什么外部查询。使用这个要求我把一些东西作为选择,因为我显然无法将多个变量相互比较,我也不确定要比较什么。

以下是db的一些上下文:

CREATE TABLE Student(
SSN INT(9),
Name VARCHAR(20),
Major VARCHAR(30),
PRIMARY KEY (SSN)
);

CREATE TABLE Course(
CourseNumber INT(5),
PrerequisiteCourseNumber INT(10),
CourseTitle VARCHAR(10),
NumberUnits INT(2),
PRIMARY KEY (CourseNumber)
);

CREATE TABLE Section(
CourseNumber INT(5),
Quarter VARCHAR(10),
RoomNumber INT(5),
DayTime VARCHAR(20),
PRIMARY KEY (CourseNumber,Quarter),
FOREIGN KEY (CourseNumber) REFERENCES Course(CourseNumber)
);


CREATE TABLE Enrollment(
SSN INT(9),
CourseNumber INT(5),
Quarter VARCHAR(10),
Grade VARCHAR(1),
PRIMARY KEY (SSN,CourseNumber,Quarter),
FOREIGN KEY (SSN) REFERENCES Student(SSN),
FOREIGN KEY (CourseNumber) REFERENCES Course(CourseNumber),
FOREIGN KEY (Quarter) REFERENCES Section(Quarter)
);

1 个答案:

答案 0 :(得分:1)

模式

CREATE TABLE Student(
SSN INT(9),
Name VARCHAR(20),
Major VARCHAR(30),
PRIMARY KEY (SSN)
);

CREATE TABLE Enrollment(
SSN INT(9),
CourseNumber INT(5),
Quarter VARCHAR(10),
Grade VARCHAR(1),
PRIMARY KEY (SSN,CourseNumber,Quarter),
FOREIGN KEY (SSN) REFERENCES Student(SSN)
-- FOREIGN KEY (CourseNumber) REFERENCES Course(CourseNumber),
-- FOREIGN KEY (Quarter) REFERENCES Section(Quarter)
);

insert student(ssn,name,major) values
(1,'John','b'),(2,'Sally','b'),(3,'Kim','b'),(4,'Stan','b');

insert enrollment(ssn,coursenumber,quarter,grade) values
(1,1,'F2015','A'),
(2,1,'F2015','A'),(2,2,'F2015','B'),
(3,1,'F2015','B'),
(4,1,'F2015','A'),(4,2,'F2015',null),(4,3,'F2015','A');

查询

select distinct s.ssn,s.name
from
(   select ssn,count(ssn) outCount
    from
    (   select e.ssn,e.grade,count(e.ssn) theCountInner
        from enrollment e
        where e.grade is not null
        group by e.ssn,e.grade
    ) xInner1
    -- where count(ssn)=1
    group by ssn
    having outCount=1
) xInner2
join student s
on s.ssn=xInner2.ssn
join enrollment
on enrollment.ssn=xInner2.ssn
and enrollment.grade='A'
+-----+------+
| ssn | name |
+-----+------+
|   1 | John |
|   4 | Stan |
+-----+------+

请注意,distinct用于删除Stan的两行,如果没有它。

注意,xInner1派生表会带回不带空值的等级,其中包含SSN级别的计数。

快速重新计算SSN&having = 1的情况。这将成为派生表xInner2

这与学生联系并且注册时找到了A.如上所述,distinct将其清理干净,因此Stan不会出现两次。

我相信还有其他方法。那是我的黑客