简体   繁体   中英

how to handle sub query in sql?

I have a table containing the following columns: id, sid, subcode, subStatus,printdate

Sid stand for student id. I want student with finalStaus.Finalstatus is base on last subcode of that sid.In first case sid is 5 and Finalstatus is Fail.Here lastsubcode is 4. In second case sid is 3 and finalstaus is promo.Here lastsubcode is 3.

Subcode can be 1,2,3,4 .....

Previously my table has 4 column.

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  

with the following query I am able to fetch same what I want.

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

I want student with finalStaus of perticular date.Here date is 5.Finalstatus is base on last subcode of that sid. Here is my query

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

With above query I am getting output.

SId SubStatus
3   pass
5   Fail

Here my logic fail.I don't want sid=3 should come.Sid having value 3,its actual last subcode is 3 but that is next day.So I modified query.

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

OUtput:

SId SubCode
5   Fail

With the above query I am getting proper output.I just want to know when I am writing subquery,

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

I also wanted to find out only count of pass substatus of student whose final status is not pass.Only want count of substatus not sid

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

Here id 1 and 2 has pass status.Here Sid is 5.But Final status of sid 5 is Fail.Because final status is base on max subcode.How to find that?

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

Ans:Neither. Subquery doesnot care about the query outside,. So it will be all sid from studentdetails filtered by the where Clause( PrintDate>= '06/06/2014' and printdate)<'06/07/2014')

For your question 2: Just wrap your first query as a cte, then the remaining is simple

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: Remember to take care of upper and lower case if this is actual data

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM