Students are absent from classes, I have to calculate consecutive absences. 'Date' table has all dates in school year, and indicates if school is in session. Not in session for weekends or holidays. 'Absence' table lists students and the dates they were absent from specific class. I need to list all dates for each 'CLASS' group to see if a class is missed for consecutive days. I have tried CROSS JOIN, couldn't get it to work. Maybe ROW_NUMBER can be used. Any type of solution is welcome!
Date table with dates school is in session. Absence tables with days a student is absent and which class. Last picture is table I want to create. I would like to repeat the dates in the range for each Student/Class group
Try something like the following. You can run this example in SSMS.
DECLARE @Absent table ( stu_id varchar(10), class varchar(10), absent_date date );
INSERT INTO @Absent VALUES
( 'Billie', 'English', '11/03/2020' ),
( 'Billie', 'Math', '11/10/2020' ),
( 'Billie', 'Math', '11/12/2020' ),
( 'Billie', 'Science', '11/19/2020' ),
( 'Billie', 'Math', '11/19/2020' );
DECLARE @InSession table ( CalDate date, InSession bit );
INSERT INTO @InSession VALUES
( '11/02/2020', 1 ),( '11/03/2020', 1 ),( '11/04/2020', 1 ),( '11/05/2020', 1 ),( '11/06/2020', 1 ),( '11/07/2020', 0 ),( '11/08/2020', 0 ),
( '11/09/2020', 1 ),( '11/10/2020', 1 ),( '11/11/2020', 0 ),( '11/12/2020', 1 ),( '11/13/2020', 1 ),( '11/14/2020', 0 ),
( '11/15/2020', 0 ),( '11/16/2020', 1 ),( '11/17/2020', 1 ),( '11/18/2020', 1 ),( '11/19/2020', 1 ),( '11/20/2020', 0 );
SELECT DISTINCT
FORMAT ( s.CalDate, 'MM/dd/yyyy' ) AS CalDate,
s.InSession,
a.stu_id,
CASE
WHEN a.absent_date = s.CalDate THEN a.class
ELSE ''
END AS class,
CASE
WHEN a.absent_date = s.CalDate THEN FORMAT ( a.absent_date, 'MM/dd/yyyy' )
ELSE ''
END AS absent_date
FROM @InSession AS s
CROSS APPLY @Absent AS a
ORDER BY
s.CalDate;
Returns
+------------+-----------+--------+---------+-------------+
| CalDate | InSession | stu_id | class | absent_date |
+------------+-----------+--------+---------+-------------+
| 2020-11-02 | 1 | Billie | | |
| 2020-11-03 | 1 | Billie | | |
| 2020-11-03 | 1 | Billie | English | 11/03/2020 |
| 2020-11-04 | 1 | Billie | | |
| 2020-11-05 | 1 | Billie | | |
| 2020-11-06 | 1 | Billie | | |
| 2020-11-07 | 0 | Billie | | |
| 2020-11-08 | 0 | Billie | | |
| 2020-11-09 | 1 | Billie | | |
| 2020-11-10 | 1 | Billie | | |
| 2020-11-10 | 1 | Billie | Math | 11/10/2020 |
| 2020-11-11 | 0 | Billie | | |
| 2020-11-12 | 1 | Billie | | |
| 2020-11-12 | 1 | Billie | Math | 11/12/2020 |
| 2020-11-13 | 1 | Billie | | |
| 2020-11-14 | 0 | Billie | | |
| 2020-11-15 | 0 | Billie | | |
| 2020-11-16 | 1 | Billie | | |
| 2020-11-17 | 1 | Billie | | |
| 2020-11-18 | 1 | Billie | | |
| 2020-11-19 | 1 | Billie | | |
| 2020-11-19 | 1 | Billie | Math | 11/19/2020 |
| 2020-11-19 | 1 | Billie | Science | 11/19/2020 |
| 2020-11-20 | 0 | Billie | | |
+------------+-----------+--------+---------+-------------+
Note that on 11/19/2020
Billie is marked absent from two classes, creating multiple results for the day.
You will also receive a blank row in addition to an "absent" row on days an absence has been reported. I'm looking to see if I can resolve this part.
UPDATE
Removed the "empty" rows on absent days.
SELECT DISTINCT
s.CalDate,
s.InSession,
a.stu_id,
ISNULL ( x.class, '' ) AS class,
ISNULL ( x.absent_date, '' ) AS absent_date
FROM @InSession AS s
CROSS APPLY @Absent AS a
OUTER APPLY (
SELECT
ab.class, CONVERT ( varchar(10), ab.absent_date, 101 ) AS absent_date
FROM @Absent AS ab
WHERE
ab.stu_id = a.stu_id
AND ab.absent_date = s.CalDate
) AS x
ORDER BY
s.CalDate, stu_id, absent_date;
Returns
+------------+-----------+--------+---------+-------------+
| CalDate | InSession | stu_id | class | absent_date |
+------------+-----------+--------+---------+-------------+
| 2020-11-02 | 1 | Billie | | |
| 2020-11-03 | 1 | Billie | English | 11/03/2020 |
| 2020-11-04 | 1 | Billie | | |
| 2020-11-05 | 1 | Billie | | |
| 2020-11-06 | 1 | Billie | | |
| 2020-11-07 | 0 | Billie | | |
| 2020-11-08 | 0 | Billie | | |
| 2020-11-09 | 1 | Billie | | |
| 2020-11-10 | 1 | Billie | Math | 11/10/2020 |
| 2020-11-11 | 0 | Billie | | |
| 2020-11-12 | 1 | Billie | Math | 11/12/2020 |
| 2020-11-13 | 1 | Billie | | |
| 2020-11-14 | 0 | Billie | | |
| 2020-11-15 | 0 | Billie | | |
| 2020-11-16 | 1 | Billie | | |
| 2020-11-17 | 1 | Billie | | |
| 2020-11-18 | 1 | Billie | | |
| 2020-11-19 | 1 | Billie | Math | 11/19/2020 |
| 2020-11-19 | 1 | Billie | Science | 11/19/2020 |
| 2020-11-20 | 0 | Billie | | |
+------------+-----------+--------+---------+-------------+
UPDATE
So I want the date range, Nov 2 - 20, repeated for every CLASS and every STUDENT included in the raw data.
Try this:
SELECT
CalDate,
InSession,
stu_id,
class,
MAX ( absent_date ) AS absent_date
FROM (
SELECT DISTINCT
CalDate,
InSession,
stu_id,
x.class,
CASE
WHEN x.absent_date = CalDate THEN CONVERT ( varchar(10), x.absent_date, 101 )
ELSE ''
END AS absent_date
FROM @InSession AS i
CROSS APPLY @Absent AS a
OUTER APPLY (
SELECT
ab.class, CONVERT ( varchar(10), ab.absent_date, 101 ) AS absent_date
FROM @Absent AS ab
WHERE
ab.stu_id = a.stu_id
AND ab.absent_date = a.absent_date
) AS x
WHERE
i.CalDate BETWEEN '11/02/2020' AND '11/30/2020'
) AS StudentAbsent
GROUP BY
CalDate, InSession, stu_id, class
ORDER BY
stu_id, class, CalDate;
Returns
+------------+-----------+--------+---------+-------------+
| CalDate | InSession | stu_id | class | absent_date |
+------------+-----------+--------+---------+-------------+
| 2020-11-02 | 1 | Billie | English | |
| 2020-11-03 | 1 | Billie | English | 11/03/2020 |
| 2020-11-04 | 1 | Billie | English | |
| 2020-11-05 | 1 | Billie | English | |
| 2020-11-06 | 1 | Billie | English | |
| 2020-11-07 | 0 | Billie | English | |
| 2020-11-08 | 0 | Billie | English | |
| 2020-11-09 | 1 | Billie | English | |
| 2020-11-10 | 1 | Billie | English | |
| 2020-11-11 | 0 | Billie | English | |
| 2020-11-12 | 1 | Billie | English | |
| 2020-11-13 | 1 | Billie | English | |
| 2020-11-14 | 0 | Billie | English | |
| 2020-11-15 | 0 | Billie | English | |
| 2020-11-16 | 1 | Billie | English | |
| 2020-11-17 | 1 | Billie | English | |
| 2020-11-18 | 1 | Billie | English | |
| 2020-11-19 | 1 | Billie | English | |
| 2020-11-20 | 0 | Billie | English | |
| 2020-11-02 | 1 | Billie | Math | |
| 2020-11-03 | 1 | Billie | Math | |
| 2020-11-04 | 1 | Billie | Math | |
| 2020-11-05 | 1 | Billie | Math | |
| 2020-11-06 | 1 | Billie | Math | |
| 2020-11-07 | 0 | Billie | Math | |
| 2020-11-08 | 0 | Billie | Math | |
| 2020-11-09 | 1 | Billie | Math | |
| 2020-11-10 | 1 | Billie | Math | 11/10/2020 |
| 2020-11-11 | 0 | Billie | Math | |
| 2020-11-12 | 1 | Billie | Math | 11/12/2020 |
| 2020-11-13 | 1 | Billie | Math | |
| 2020-11-14 | 0 | Billie | Math | |
| 2020-11-15 | 0 | Billie | Math | |
| 2020-11-16 | 1 | Billie | Math | |
| 2020-11-17 | 1 | Billie | Math | |
| 2020-11-18 | 1 | Billie | Math | |
| 2020-11-19 | 1 | Billie | Math | 11/19/2020 |
| 2020-11-20 | 0 | Billie | Math | |
| 2020-11-02 | 1 | Billie | Science | |
| 2020-11-03 | 1 | Billie | Science | |
| 2020-11-04 | 1 | Billie | Science | |
| 2020-11-05 | 1 | Billie | Science | |
| 2020-11-06 | 1 | Billie | Science | |
| 2020-11-07 | 0 | Billie | Science | |
| 2020-11-08 | 0 | Billie | Science | |
| 2020-11-09 | 1 | Billie | Science | |
| 2020-11-10 | 1 | Billie | Science | |
| 2020-11-11 | 0 | Billie | Science | |
| 2020-11-12 | 1 | Billie | Science | |
| 2020-11-13 | 1 | Billie | Science | |
| 2020-11-14 | 0 | Billie | Science | |
| 2020-11-15 | 0 | Billie | Science | |
| 2020-11-16 | 1 | Billie | Science | |
| 2020-11-17 | 1 | Billie | Science | |
| 2020-11-18 | 1 | Billie | Science | |
| 2020-11-19 | 1 | Billie | Science | 11/19/2020 |
| 2020-11-20 | 0 | Billie | Science | |
+------------+-----------+--------+---------+-------------+