Josh Trutwin <[EMAIL PROTECTED]> wrote on 09/21/2004 09:40:03 AM:

> On Tue, 21 Sep 2004 08:57:21 -0400
> [EMAIL PROTECTED] wrote:
> 
> <snip>
> 
> <snip again>
> 
> Perhaps another example would help.  I've been trying to re-write
> another join query that's designed to produce an attendance record for
> each student detailing which classes they've attended and which
> they've missed.  Each occurrence of a student (PK tech_id) attending a
> class (PK c_id) is recorded in an intersection table class_attneded
> (tech_id, c_id PK).  The absence of a record in this table indicates
> the student missed the class.  So if tech_id 123123 was at classes 1
> and 3, there would be records in the class_attended table:
> 
> tech_id - class_id
> 123123    1
> 123123    3
> 
> The query that worked pre 5.0.1 is:
> 
> SELECT *
>   FROM student s
>  INNER JOIN enrollment e ON e.tech_id = s.tech_id
>  INNER JOIN class_attended ca ON ca.tech_id = s.tech_id
>  RIGHT JOIN class c ON c.c_id = ca.c_id
>  WHERE s.tech_id = '253542'
>    AND c.term_id = '4'
>    AND c.class_date < NOW()
>  ORDER BY week_no;
> 
> In my mind I see this as get all the class records (the table on the
> right side of the RIGHT JOIN) and if you can match up the
> class_attended, enrollment and student information do so, otherwise
> set those values to NULL.  In the example above this yeilds 3 rows -
> the for for class id 2 has NULLs in the other table data.
> 
> I cannot seem to figure out the 5.0.1 equivalent because I seem to
> have learned this the wrong way.
> 
> I tried this, starting with the class table since those are the rows
> that I want to have displayed regardless of matches.
> 
> SELECT *
>   FROM class c
>   LEFT JOIN class_attended ca ON c.c_id = ca.c_id
>  INNER JOIN student s ON ca.tech_id = s.tech_id AND ca.tech_id =
> '253542'
>  INNER JOIN enrollment e ON e.tech_id = s.tech_id
>  WHERE c.term_id = '4'
>    AND c.class_date < NOW()
>  ORDER BY week_no;
> 
> This acts like an INNER JOIN though, I can only get two rows.  I've
> tried mucking around with it, but I just cannot get the "outer" row
> for class id = 2 to show.
> 
> This was so much easier with the bug!  :)
> 
> Thanks for your help,
> 
> Josh
> 

Hmmm. you want to see a student, all of the classes they are enrolled in 
and how many times they attended? I understand the relationships between 
the student, class, and class_attended tables (that's all related to 
attendance and class scheduling) but I do not understand the relationship 
between student and class. Is that the enrollment table? Does enrollment 
have a "class id" field on it? Are there other tables I do not know about 
that can tell you if a student is _supposed_ to be in a class? If 
enrollment does relate a student to a class, I propose the following query

SELECT s.tech_id, s.name, c.c_id, c.name, count(ca.id) as days_present, 
count(c.c_id) as classes_held
FROM student s
INNER JOIN enrollment e
        on e.tech_id = s.tech_id
INNER JOIN class c
        on c.c_id = e.c_id
LEFT JOIN class_attended ca
        on ca.c_id = c.c_ID
WHERE s.tech_ID = 253542
        AND c.term_id = 4
        AND c.class_date < NOW()
GROUP BY 1,2,3,4

I used a little MySQL shorthand with that query (I used column numbers in 
the GROUP BY instead of field names) and I eliminated the single quotes 
around your numbers (they WERE numbers not strings, right?). 

If I deduced your entity relationships correctly, this should tell you all 
of the classes that a person (tech_id=253542) was enrolled in for a term 
(term_id=4) for classes that have already happened (class_date < NOW()), 
how many times that person has be counted present (count(ca.id)), and how 
many classes there have been so far (count(c.c_id)).

I think we are close. 

Shawn Green
Database Administrator
Unimin Corporation - Spruce Pine





Reply via email to