Easy SQL Plus查询(分组依据)

时间:2011-10-12 17:02:11

标签: sql oracle greatest-n-per-group

我正在尝试以下列方式查询我的数据库:

查找最年轻学生的姓名,专业和年龄,该学生可以是数学专业,也可以参加由计算机科学教授授课的课程。

架构如下:

STUDENT(*snum: integer, sname: string, major: string, slevel: string, age: integer) 
CLASS(*name: string, meets_at: date, room: string, fid: integer) 
ENROLLED(*snum:integer, *cname: string ) 
FACULTY(*fid: integer, fname: string, deptid: integer) 
DEPARTMENT (*deptid: integer,dname: string, Location:string)

(The fields with '*' are primary keys.)

我编写了以下查询,正确查找了学生,但我无法弄清楚如何打印名称和专业。

SELECT MIN(s.age) 
FROM   student s 
WHERE  ( s.major = 'Math' ) 
        OR s.snum IN (SELECT e.snum 
                      FROM   class c, 
                             enrolled e, 
                             faculty f, 
                             department d 
                      WHERE  e.cname = c.NAME 
                             AND c.fid = f.fid 
                             AND d.dname = 'Computer Sciences'); 

我尝试了以下操作并得到了错误:“不是单组组功能”

SELECT s.sname, 
       s.major, 
       MIN(s.age) 
FROM   student s 
WHERE  ( s.major = 'Math' ) 
        OR s.snum IN (SELECT e.snum 
                      FROM   class c, 
                             enrolled e, 
                             faculty f, 
                             department d 
                      WHERE  e.cname = c.NAME 
                             AND c.fid = f.fid 
                             AND d.dname = 'Computer Sciences'); 

有什么想法吗? SQLPlus的新手,所以我还在尝试学习如何构建查询。提前谢谢!

2 个答案:

答案 0 :(得分:2)

简单方法:只需将您查询的查询设置为子查询:

SELECT *
FROM
student where age =
(
SELECT MIN(s.age) 
FROM   student s 
WHERE  ( s.major = 'Math' ) 
        OR s.snum IN (SELECT e.snum 
                      FROM   class c, 
                             enrolled e, 
                             faculty f, 
                             department d 
                      WHERE  e.cname = c.NAME 
                             AND c.fid = f.fid 
                             AND d.dname = 'Computer Sciences')) 

如果你想要更优雅的东西,我会多考虑一下。

请注意,如果您有多个该年龄的学生,您可能会获得多行。

答案 1 :(得分:1)

您需要添加GROUP BY子句。

试试这个:

SELECT s.sname, 
       s.major, 
       MIN(s.age) 
FROM   student s 
WHERE  ( s.major = 'Math' ) 
        OR s.snum IN (SELECT e.snum 
                      FROM   class c, 
                             enrolled e, 
                             faculty f, 
                             department d 
                      WHERE  e.cname = c.NAME 
                             AND c.fid = f.fid 
                             AND d.dname = 'Computer Sciences')
GROUP BY s.sname,s.major;

另外,还有一个可选的HAVING子句,允许您将谓词应用于分组信息。例如,如果您想要相同的结果,但仅适用于年龄超过25岁的人,您可以写:     SELECT s.sname,            s.major,            MIN(s.age)     来自学生     在哪里(s.major ='数学')             或者s.snum IN(选择e.snum                           从班级c,                                  报名参加e,                                  教师f,                                  部门                           WHERE e.cname = c.NAME                                  AND c.fid = f.fid                                  AND d.dname ='计算机科学')     GROUP BY s.sname,s.major     HAVING MIN(s.age)> = 25;

请注意,将MIN(s.age)放入WHERE子句将不起作用。 HAVING子句是将谓词应用于分组信息的方法。

希望有所帮助,

-Mark