如何在sql中处理子查询?

时间:2014-06-05 10:02:13

标签: sql

我有一个包含以下列的表:id,sid,subcode,subStatus,printdate

Sid代表学生身份。我希望学生使用finalStaus.Finalstatus基于该sid的最后一个子代码。在第一种情况下,sid为5,Finalstatus为Fail.Here lastsubcode为4。 在第二种情况下,sid是3,finalstaus是promo.Here lastsubcode是3。

子代码可以是1,2,3,4 .....

以前我的表有4列。

Id    SId   SubCode  SubStatus     
1     5       4       Fail         
2     5       3       pass         
3     5       2       pass         
4     5       1       fail         
5     3       3       promo        
7     3       2       promo        
8     3       1       pass  

使用以下查询,我可以获取我想要的内容。

SELECT studentdetails.SId, studentdetails.substatus
FROM studentdetails
JOIN (
  SELECT studentdetails.sid, MAX(studentdetails.subcode) AS max_subcode
  FROM studentdetails
  GROUP BY studentdetails.sid
) m ON m.sid=studentdetails.sid AND m.max_subcode=studentdetails.subcode

Now I added extra column
Id    SId   SubCode  SubStatus     PrintDate
1     5       4       Fail         2014-06-05 17:00:00.000
2     5       3       pass         2014-06-05 17:10:00.000
3     5       2       pass         2014-06-05 17:20:00.000
4     5       1       fail         2014-06-05 17:40:00.000
5     3       3       promo        2014-06-06 00:20:00.000
7     3       2       promo        2014-06-06 00:10:00.000
8     3       1       pass         2014-06-05 11:59:00.000

我希望学生能够获得特定日期的finalStaus。这里的日期是5.Finalstatus基于该sid的最后一个子代码。 这是我的查询

SELECT studentdetails.SId, studentdetails.substatus
FROM studentdetails
JOIN (
  SELECT studentdetails.sid, MAX(studentdetails.subcode) AS max_subcode
  FROM studentdetails
  where PrintDate>= '06/05/2014' and printdate <'06/06/2014'
  GROUP BY studentdetails.sid
) m ON m.sid=studentdetails.sid AND m.max_subcode=studentdetails.subcode

通过上述查询,我​​得到输出。

SId SubStatus
3   pass
5   Fail

这里我的逻辑失败了。我不希望sid = 3应该来。具有值3,它的实际最后一个子码是3但是那是第二天。所以我修改了查询。

SELECT studentdetails.SId, studentdetails.substatus
FROM studentdetails
JOIN (
  SELECT studentdetails.sid, MAX(studentdetails.subcode) AS max_subcode
  FROM studentdetails
  where PrintDate>= '06/05/2014' and printdate <'06/06/2014'
  and SId not in (Select SId from studentDetails where  PrintDate>= '06/06/2014' and printdate <'06/07/2014')
  GROUP BY studentdetails.sid
) m ON m.sid=studentdetails.sid AND m.max_subcode=studentdetails.subcode

输出:

SId SubCode
5   Fail

通过上面的查询我得到了正确的输出。我只是想知道我什么时候写子查询,

SId not in : Here which sid will consider from 1 or 2.

1  sid from (SELECT studentdetails.sid, MAX(studentdetails.subcode) AS max_subcode
      FROM studentdetails
      where PrintDate>= '06/05/2014' and printdate <'06/06/2014')

   SId SubStatus
    3   pass
    5   Fail

2 all sid from studentdetails

我还想找出最终状态未通过的学生通过次数的计数。只想要数量而不是sid

   Id    SId   SubCode  SubStatus     
    1     5       4       Fail         
    2     5       3       pass         
    3     5       2       pass         
    4     5       1       fail 

这里id 1和2有通过状态。这里是Sid 5.But sid 5的最终状态是Fail.Because最终状态是基于max子码。如何找到?

1 个答案:

答案 0 :(得分:0)

问题1. SId不在:这里sid将考虑从1还是2?

答:都不是。子查询不关心外面的查询。因此,所有sid都来自于学生详细信息,过滤条款(PrintDate&gt; =&#39; 06/06 / 2014&#39;和printdate)&lt;&#39; 06/07 / 2014&#39;)

对于你的问题2:只需将你的第一个查询包装为cte,然后剩下的就是简单

with cte (SId,SubStatus)as(
    SELECT studentdetails.SId, studentdetails.substatus
    FROM studentdetails
    JOIN (
      SELECT studentdetails.sid, MAX(studentdetails.subcode) AS max_subcode
      FROM studentdetails
      GROUP BY studentdetails.sid
    ) 
    m ON m.sid=studentdetails.sid AND m.max_subcode=studentdetails.subcode)

    select SId,count(SubStatus) as PassCount from studentdetails 
where SId in(select SId from cte where SubStatus <> 'pass') 
and SubStatus = 'pass' group by SId

PS:如果这是实际数据,请记住要处理大写和小写