Search code examples
sqloracle-databasejoinleft-joinnvl

Displaying records with a column value 0 when there is no record


I have following tables:

enter image description here

Schema

tbl_semester_empid {id, semester_name varchar(50), start_date}

tbl_batch_empid {id, semester_id,batch_name, session_room}

tbl_associate_empid {id, associate_name, batch_id, contact, joining_date, induction_result, stream_result int}

The problem query is: Display semester wise associate count.

I have wrote 3 queries:

--basic query
SELECT s.ID "Semester Id", COUNT(*) "Associate Count" FROM TBL_SEMESTER_593932 s, TBL_ASSOCIATE_593932 a, TBL_BATCH_593932 b 
        WHERE s.ID=b.SEMESTER_ID AND a.BATCH_ID=b.ID  
                GROUP BY s.ID;

--used NVL function
SELECT s.ID "Semester Id", NVL(COUNT(*),0) "Associate Count" FROM TBL_SEMESTER_593932 s, TBL_ASSOCIATE_593932 a, TBL_BATCH_593932 b 
        WHERE s.ID=b.SEMESTER_ID AND a.BATCH_ID=b.ID  
                GROUP BY s.ID;

-- used LEFT OUTER JOIN and  JOIN
SELECT s.ID "Semester Id", NVL(COUNT(*),0) "Associate Count" 
        FROM TBL_SEMESTER_593932 s LEFT OUTER JOIN TBL_BATCH_593932 b ON s.ID=b.SEMESTER_ID 
             JOIN TBL_ASSOCIATE_593932 a ON a.BATCH_ID=b.ID  
                   GROUP BY s.ID;

All of them display following output (it shows records corresponding to only those semesters which have at least 1 student in it, if theis is no student in that semester, no information for that semester is displayed):

enter image description here

I want the semesters with no associates in them as 0 in Associates Count column. So I tried the same with two LEFT OUTE JOINs:

SELECT s.ID "Semester Id", NVL(COUNT(*),0) "Associate Count" 
    FROM TBL_SEMESTER_593932 s LEFT OUTER JOIN TBL_BATCH_593932 b ON s.ID=b.SEMESTER_ID 
         LEFT OUTER JOIN TBL_ASSOCIATE_593932 a ON a.BATCH_ID=b.ID  
                GROUP BY s.ID;

However the result is weird:

enter image description here


Solution

  • Basically, what you have to do is to use a list of all semester available and then calculate the amount for each one:

    select s.ID, 
           s.Semester_Name,
           NVL ((select count(*) 
              from TBL_ASSOCIATE_593932 a
                   join TBL_BATCH_593932 b 
                     on a.BATCH_ID=b.ID
            where  s.ID=b.SEMESTER_ID
           ),0) as Amount
     from TBL_SEMESTER_593932 s
    

    another approach would be left joining your list of all semesters and then count

    select s.ID, 
           s.Semester_Name,
           count(*) as Amount 
     from TBL_SEMESTER_593932 s
            left join (
              TBL_BATCH_593932 b
              join TBL_ASSOCIATE_593932 a  
                on a.BATCH_ID=b.ID)
               on s.ID=b.SEMESTER_ID
    
    group by s.ID, s.Semester_Name
    order by s.ID
    

    [Edit]: The last query was corrected according to @Mahesha999.