如何在sqldeveloper中使用IF-else条件检索最新实例

如何在sqldeveloper中使用IF-else条件检索最新实例,sql,oracle,oracle10g,Sql,Oracle,Oracle10g,我有一张学生表,如下所示 如果SUBJECT='M'至少有一条记录,则根据版本id检索SUBJECT'M'的最新记录。 ELSIF如果至少有一条SUBJECT='S'记录,则根据版本id检索SUBJECT'S'的最新记录。 ELSIF如果主题='E'至少有一条记录,则根据版本id检索主题'E'的最新记录。 否则不获取任何记录。 基于上述条件,我试图编写一个查询或视图,可以满足上述所有条件,并给出以下输出。请为我提供可能的解决方案 输出 ROLL | STUDENT | SUBJECT |

我有一张学生表,如下所示


如果SUBJECT='M'至少有一条记录,则根据版本id检索SUBJECT'M'的最新记录。
ELSIF如果至少有一条SUBJECT='S'记录,则根据版本id检索SUBJECT'S'的最新记录。
ELSIF如果主题='E'至少有一条记录,则根据版本id检索主题'E'的最新记录。
否则不获取任何记录。

基于上述条件,我试图编写一个查询或视图,可以满足上述所有条件,并给出以下输出。请为我提供可能的解决方案

输出

ROLL  |  STUDENT | SUBJECT | VERSION_ID | 
  3        C         M         3
Create table student (ROLL number,STUDENT varchar2(20),SUBJECT varchar2(20),VERSION_ID number );  
insert into STUDENT values(1,'A','M',1);
insert into STUDENT values(2,'B','M',2);
insert into STUDENT values(3,'C','M',3);
insert into STUDENT values(4,'B','S',1);
insert into STUDENT values(5,'D','S',2);
insert into STUDENT values(6,'E','E',1);
insert into STUDENT values(7,'F','G',1);  
我尝试使用下面的查询获得所需的输出,但遇到了错误。请帮助我以更好的性能解决此查询

SELECT * from ( IF EXISTS(select subject from STUDENT where SUBJECT='M') then
select * from STUDENT S1
inner join
(select S2.ROLL from STUDENT S2
      where 
          S2.ROLL=(select S3.ROLL from STUDENT S3
                       where S3.SUBJECT='M'
                   and S3.VERSION_ID=(select MAX(S4.VERSION_ID) from STUDENT S4
                           GROUP BY S4.SUBJECT
                           HAVING S4.SUBJECT='M'))) S5
ON
S1.ROLL=S5.ROLL
ELSIF EXISTS(select subject from STUDENT where SUBJECT='S') then
select * from STUDENT S1
inner join
(select S2.ROLL from STUDENT S2
      where 
          S2.ROLL=(select S3.ROLL from STUDENT S3
                       where S3.SUBJECT='S'
                   and S3.VERSION_ID=(select MAX(S4.VERSION_ID) from STUDENT S4
                           GROUP BY S4.SUBJECT
                           HAVING S4.SUBJECT='S'))) S5
           ON
          S1.ROLL=S5.ROLL
ELSIF EXISTS(select subject from STUDENT where SUBJECT='E') then
select * from STUDENT S1
inner join
(select S2.ROLL from STUDENT S2
      where 
          S2.ROLL=(select S3.ROLL from STUDENT S3
                       where S3.SUBJECT='E'
                   and S3.VERSION_ID=(select MAX(S4.VERSION_ID) from STUDENT S4
                           GROUP BY S4.SUBJECT
                           HAVING S4.SUBJECT='E'))) S5
           ON
          S1.ROLL=S5.ROLL
ELSE 
  SELECT * FROM STUDENT WHERE 1=2);
表格创建:

ROLL  |  STUDENT | SUBJECT | VERSION_ID | 
  3        C         M         3
Create table student (ROLL number,STUDENT varchar2(20),SUBJECT varchar2(20),VERSION_ID number );  
insert into STUDENT values(1,'A','M',1);
insert into STUDENT values(2,'B','M',2);
insert into STUDENT values(3,'C','M',3);
insert into STUDENT values(4,'B','S',1);
insert into STUDENT values(5,'D','S',2);
insert into STUDENT values(6,'E','E',1);
insert into STUDENT values(7,'F','G',1);  
插入数据:

ROLL  |  STUDENT | SUBJECT | VERSION_ID | 
  3        C         M         3
Create table student (ROLL number,STUDENT varchar2(20),SUBJECT varchar2(20),VERSION_ID number );  
insert into STUDENT values(1,'A','M',1);
insert into STUDENT values(2,'B','M',2);
insert into STUDENT values(3,'C','M',3);
insert into STUDENT values(4,'B','S',1);
insert into STUDENT values(5,'D','S',2);
insert into STUDENT values(6,'E','E',1);
insert into STUDENT values(7,'F','G',1);  

谢谢。

我们可以使用您在问题中给出的排序逻辑,将
行数
应用于整个表。受试者
M
S
E
的优先级依次为
VERSION\u ID
。主题与这三个主题不匹配的行被分配最低优先级。如果没有匹配主题的记录,我们将过滤掉
WHERE
子句中的所有记录

WITH cte AS (
    SELECT ROLL, STUDENT, SUBJECT, VERSION_ID,
        ROW_NUMBER() OVER (ORDER BY CASE WHEN SUBJECT = 'M' THEN 1
                                         WHEN SUBJECT = 'S' THEN 2
                                         WHEN SUBJECT = 'E' THEN 3
                                         ELSE 4 END, VERSION_ID DESC END) rn
)

SELECT ROLL, STUDENT, SUBJECT, VERSION_ID
FROM cte
WHERE rn = 1 AND SUBJECT IN ('M', 'S', 'E')

你想要正确的答案,对吗?试试这个:

SELECT TOP 1 #student.*
FROM   student
JOIN   (

SELECT  MAX(VERSION_ID) VERSION_ID,SUBJECT
FROM   student
WHERE  SUBJECT = 'M'
GROUP BY SUBJECT

UNION ALL 

SELECT  MAX(VERSION_ID),SUBJECT
FROM   student
WHERE  SUBJECT = 'S'
GROUP BY SUBJECT

UNION ALL

SELECT  MAX(VERSION_ID),SUBJECT
FROM   student
WHERE  SUBJECT = 'E'
GROUP BY SUBJECT

UNION ALL 

SELECT  MAX(VERSION_ID),SUBJECT
FROM   student
WHERE  SUBJECT = 'G'
GROUP BY SUBJECT

UNION ALL

SELECT NULL,NULL

)       AS Dtls
ON     (student.SUBJECT     =      Dtls.SUBJECT
AND student.VERSION_ID     =      Dtls.VERSION_ID)

嗨,蒂姆,谢谢你的快速回复。在这种情况下,此查询将提供预期的输出。但若受试者M不可用,则查询应给出受试者S的最新记录,即
5,'D',S',2
。若主题“M”和“S”都不在表中,则查询应检查主题“E”,即
6,“E”,“E”,1
。这个查询在任何情况下都有效吗?@jhulan是的,我相信会的。你测试过我的查询了吗?如果您发现它在某些边缘情况下实际上失败了,那么请删除一条评论,它可以被更新。谢谢Tim,这很好。很抱歉,我没有进行测试就发表了评论,这是一个非常简单和简短的解决方案。我相信这对某些人来说很有用,但问题被标记为Oracle,它没有
TOP1
。(它只有
fetch第一行
,但问题也被标记为Oracle10g,这是一个古老的版本,也没有这个。)