在PostgreSQL中从另一个表中减去一个表

时间:2013-12-10 15:01:35

标签: sql postgresql

我有一张包含学生ID及其GPA的表格。

_____________
| sID | GPA |
-------------
|  1  | 3.7 |
|  2  | 3.9 |
|  3  | 3.6 |
|  4  | 3.7 |
|  5  | 3.1 |
|  6  | 3.9 |

我想创建一个表格,只给出GPA最高或次高的学生。换句话说,我想要这个结果:

_____________
| sID | GPA |
-------------
|  2  | 3.9 |
|  6  | 3.9 |
|  1  | 3.7 |
|  4  | 3.7 |

为此,我首先编写了一个查询,为我提供了所有匹配得分最高的学生:

SELECT * 
FROM gpaTable
WHERE gpa in (
      SELECT max(gpa) FROM gpaTable)

这给了我:

| sID | GPA |
-------------
|  2  | 3.9 |
|  6  | 3.9 |

为了获得第二高,我想从整个原始表中减去此结果,然后重复再次找到max的查询。

我认为它看起来像这样,但是,我做不到。

SELECT *
FROM gpaTable
WHERE gpa IN (
    SELECT * 
    FROM gpaTable
    WHERE gpa in (
          SELECT max(gpa) FROM gpaTable)
    )
 OR
    (SELECT *
     FROM gpaTable
     WHERE NOT EXISTS IN
           (SELECT * 
            FROM gpaTable
            WHERE gpa in (
            SELECT max(gpa) FROM gpaTable)
    )

在英语中,查询说(或应该说)在最大GPA表中为我提供最大GPA OR 表中的每一行较小的GPA

我真的很感激任何帮助!

3 个答案:

答案 0 :(得分:1)

选择subselect中的前2个条目会不会更容易?例如,您可以使用LIMIT

SELECT * 
FROM gpaTable
WHERE gpa in (SELECT DISTINCT gpa FROM gpaTable ORDER BY gpa DESC LIMIT 2) ORDER BY gpa;

答案 1 :(得分:1)

你可以这样做:

select *
from gpaTable
where gpa in (
  select distinct gpa
  from gpaTable
  order by gpa desc
  limit 2
)

这个想法类似于您的第一个解决方案,除了MAX被排序和LIMIT 2

取代

Demo on sqlfiddle.

答案 2 :(得分:1)

SELECT sid, gpa
FROM (
   select sid, 
          gpa, 
          dense_rank() over (order by gpa desc) as rnk
   from gpaTable
) t
where rnk <= 2
order by sid;