1

我有一个名为 RESULTS 的表,如下所示:

RESULTS_IDN    NAME    SUBJECT    YEAR    QUALIFIED
1              MARK    ENGLISH    1989    N
3              MARK    ENGLISH    1991    N
5              MARK    ENGLISH    1993    Y
7              MARK    ENGLISH    1995    N
2              MARK    MATH       1990    N
5              MARK    MATH       1993    N
6              MARK    MATH       1995    Y
4              MARK    SCIENCE    1991    N
9              MARK    SCIENCE    1997    Y

我需要知道他写的最新考试的主题的候选人的资格状态,我如何为此编写查询(ORACLE/MSSQL)?

例如输入

NAME,SUBJECT  OUTPUT NAME IDN SUBJECT YEAR Q
MARK,ENGLISH  OUTPUT MARK 7   ENGLISH 1995 N 
MARK SCIENCE  OUTPUT MARK 9   SCIENCE 1997 Y
MARK MATH     OUTPUT MARK 6   MATH    1995 Y

我知道解决这个问题的一种方法。

(SELECT NAME SUBJECT YEAR MAX(YEAR) YEAR
FROM RESULTS WHERE NAME = 'MARK' AND SUBJECT ='MATH'
GROUP BY NAME SUBJECT YEAR) LATEST 

将 IDN 上的上表加入到同一个表中,我可以得到结果。但这是双重工作。无论如何,我可以使用 HAVING CLAUSE 或其他方式获得 MAX(YEAR) 并获得相应的年份吗?我需要对 GROUP BY 数据进行 2 次操作,一个最新的,以及对应的 Qualified 状态。

PS:当然数据库中有100个这样的候选人的记录。

更新:根据答案 2,这个问题也被归类为 每组最大 n 个问题。有趣的是,它是 DB 中的一个分类问题。

4

2 回答 2

3

在 Oracle 和 SQL Server 中,您可以使用分析/窗口函数 RANK() 或 ROW_NUMBER() 来实现此目的:

select *
  from ( select a.*
              , rank() over ( partition by name, subject order by year desc ) rnk
           from ... a
                )
 where rnk = 1

RANK() 将为最新的每一行返回 1namesubject, ROW_NUMBER() 将返回一个随机行。

仅在 Oracle 中,您可以使用KEEP为您提供相同的结果:

select name, subject, max(year) as year
     , max(qualified) keep (dense_rank first order by year desc) as qualified
  from ...
 group by name, subject
于 2013-06-29T13:04:39.907 回答
1

所有时间重新发明的问题:

SELECT t1.*
FROM RESULTS AS t1
LEFT JOIN RESULTS AS t2
  ON t1.NAME = t2.NAME AND t1.SUBJECT = t2.SUBJECT AND t1.YEAR < t2.YEAR
WHERE t2.NAME IS NULL
于 2013-06-29T17:41:47.133 回答