简体   繁体   中英

Confusion in building sql query in sql server

My table looks exactly like below

School              Course              Date             Status

SCH1            SCH1CRS1        2011-01-15           S

                SCH1CRS1        2011-01-17           C

SCH1            SCH1CRS2        2011-01-15           S

SCH2            SCH2CRS1        2011-01-15           S

                SCH2CRS1        2011-01-21           C

SCH2             SCH2CRS2        2011-01-22          S

               SCH2CRS2          2011-01-25          C

Status S=Started and C=Completed and date is start date and completed date. When a course started, user enters schoolID, courseID,Date and status, But when a course is completed, user enters courseID, Date and status. User does not enter SchoolID. From the table we can understand that SCH1CRS1 and SCH1CRS2 belongs to SCH1. What i need to know is, In a particular school, on a particular date, how many courses started but not completed.

You can see in SCH1, on 2011-01-15 two courses have started, but only one is completed. It doesn't matter when the course is completed. All i need to know is completed or not. In SCH2, two courses started on different dates, but both are completed.

Result table should be like this

Input Date: 2011-01-15

School             Not completed  

SCH1                       1

SCH2                       0

Input Date: 2011-01-22

School           Not Completed

SCH2                      0 

I think this is a messy table and database design rules are not followed. But this is what i have . No option.

Thanks

You have to find the completed course related to the started course, and if there is no completed course, count 1.

SELECT startedCourse.School AS School, 
       SUM(CASE WHEN completedCourse IS NULL THEN 1 ELSE 0 END) AS NotCompleted
FROM MyTable startedCourse
    LEFT OUTER JOIN MyTable completedCourse
        ON startedCourse.Status = 'S'
        AND completedCourse.Status = 'C'
        AND startedCourse.Course = completedCourse.Course
WHERE startedCourse.Date = ?
GROUP BY startedCourse.School

from the top of my head :

select c_started.courseID, c_started.courseDate as StartDate, c_completed.courseDate as CompletedDate, 
case 
 when c_completed.courseDate IS NULL then 'incomplete'
 Else 'completed'
end as courseStatus
from tbCourses as c_started
left join tbCourses as c_completed on c_started.courseID = c_completed.courseID 
and c_started.courseDate < c_completed.courseDate
where c_started.Status = 'S'

Would give you something like the following :

courseID -- StartDate -- CompletedDate -- courseStatus

course1 -- 2010-01-12 -- 2010-02-25 -- completed

course2 -- 2011-01-21 -- NULL -- incomplete

course3 -- 2010-10-15 -- NULL -- incomplete

How about this:

declare @InputDate datetime = '20110115';

with cCourseList as (

select  t1.School, t1.Course, DateStarted = t1.Date,
        t2.DateCompleted
from    tbl t1
outer apply 
        (select  top(1) DateCompleted = t2.Date
        from    tbl t2
        where   t2.Course = t1.Course
            and t2.Status = 'C'
        order by t2.Date) t2
where   t1.Status = 'S'

)

select  cl.School, 
        [Not Completed] = sum(case when cl.DateCompleted is null then 1 else 0 end)
from    cCourseList cl
where   cl.DateStarted <= @InputDate
group by cl.School;

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