Home > database >  How to optimise SQL query without using NOT IN
How to optimise SQL query without using NOT IN

Time:09-27

I have this Student table:

Id   companyId    status
----------------------------------------
101  1001         In-Progress
102  1001         In-Progress
103  1001         Final
104  1002         In-Progress   
105  1003         Pending With Company 
106  1003         In-Progress
107  1004         In-Progress
108  1004         In-Progress 
109  1005         In-Progress
110  1005         Completed
111  1006         In-Progress
112  1006         Canceled
113  1007         In-Progress
114  1007         Pending with Student 

I want output with these conditions:

  1. Status is "In-Progress"
  2. If have repeated companyId then other allowed staus is Completed, Canceled (Basically only allowed combination of the staus is In-Progress, Completed and Canceled)

With above condition o/p will look like this:

Id   companyId    status
--------------------------------
104  1002         In-Progress   
107  1004         In-Progress
108  1004         In-Progress 
109  1005         In-Progress
111  1006         In-Progress

We can achieve this by using NOT IN

SELECT * 
FROM student
WHERE status = 'In-Progress' 
  AND companyId NOT IN (SELECT companyId FROM student 
                        WHERE status IN ('Final', 'Pending With Company ', 'Pending with Student'));

But I'm looking for a solution without using NOT IN.

CodePudding user response:

You can use not exists

SELECT * 
  FROM student a
 WHERE a.status = 'In-Progress' 
   AND NOT EXISTS (SELECT null
                     FROM student b
                    WHERE a.companyid=b.companyid
                      AND b.status not in ('In progress','Completed','Cancelled')
                   )

CodePudding user response:

you can achieve it using left join and choosing not match rows:

   SELECT * FROM student a LEFT JOIN 
   ( SELECT companyId FROM student WHERE status in
   ('Final','Pending With Company ','Pending with Student')) b
   on a.companyid=b.companyId 
   where b.companyId is null
   and a.status = 'In-Progress' 

CodePudding user response:

WITH status as (
   select 1 as s,'In-Progress' d union all
   select 100 as s,'Final' d union all
   select 100 as s,'Pending With Company' d union all
   select 100 as s,'Pending with Student' d union all
   select 1 as s,'Cancelled' d union all
   select 1 as s,'Completed'
)
SELECT * FROM (
   SELECT 
      s.Id, 
      s.CompanyID, 
      s.status,
      MAX(status.s) OVER (partition by s.CompanyId) m
   FROM student s
   LEFT jOIN status ON s.status = status.d
) x where x.m=1 and x.status='In-Progress'

Remember, above is simply not using NOT IN. Discussion about this query not being performant is different.

  •  Tags:  
  • sql
  • Related