Question

I need a bit of help with Databases , at school we have to work on Fox Pro (I know it's old but what can I do) and one of the tasks says the following: "List the longest course from each of the teachers".

The tables we have are

Courses -> idc (primary key) , id , name , length

Teachers -> id (primary key) , name

Is there any way of doing this with the select command ? There would have to be 2 columns I believe in the end teachers.name and courses.name ... I mean the teacher would have to be unique and have next to it a max from courses but only from the ones he/she is teaching...

I have tried:

1)SELECT teachers.name,courses.name,MAX(courses.legth) FROM teachers,courses WHERE teachers.id=courses.id ---> Error

2)SELECT teachers.name,courses.name FROM teachers,courses WHERE courses.legth=(SELECT MAX(courses.length) FROM courses) AND courses.id=teachers.id ---> Only shows the longest course

3)Making a program something like:

BOF()
i=1
CALCULATE MAX(teachers.id) TO y
DO WHILE i<y
    IF teachers.id=i
        x=SELECT MAX(courses.legth) FROM courses,teachers WHERE teachers.id=i
        LIST teachers.name,courses.name FOR courses.legth=x
        SKIP
        i=i+1
     ENDIF
ENDDO

---> That one goes on forever with no result.


After some time I managed to do something about it but in a very ugly form , I'm sure there has to be a better way:

i=1
USE teachers
CALCULATE MAX(id) TO y
USE
DO WHILE i<=y
    USE courses
    CALCULATE MAX(length) FOR id=i TO x
    USE
    USE teachers
    LIST name for id=i
    USE
    USE courses
    LIST name for id=i AND length=x
    USE
    i=i+1
ENDDO

Thank you.

Was it helpful?

Solution

Yes, others have been giving you a hard time, but now you know to show what you have seriously attempted to do for problem solving. Although none have worked for you, I will try to help by explaining as I go.

First, start with the courses table alone as that has the ID of the teacher we can work with after. This is a simple group by clause.

select ;
      c.id, ;
      max( c.length ) as CourseMaxLen ;
   from ;
      courses c ;
   group by ;
      c.id ;
   into ;
      cursor C_MaxCoursePerTeacher

Then, you could browse this result to see. Now, you have a very simple query per teacher. You can then use this as the basis to join to the teacher table to get the teacher name. Then join again back to the original courses table by the teacher and length of the course. However, if you have a teacher that has multiple courses of the same length, each of the same length will be returned.

select
      CMax.ID, ;
      T.Name as TeacherName, ;
      c2.Name as CourseName,;
      c2.Length ;
   from ;
      ( select ;
             c.id, ;
             max( c.length ) as CourseMaxLen ;
          from ;
             courses c ;
          group by ;
             c.id ) CMax ;
         JOIN Teachers t ;
            on CMax.ID = t.id ;
         JOIN Courses c2 ;
            on CMax.ID = c2.ID ;
            AND CMax.CourseMaxLen = c2.Length

Notice the join to the courses (c2) is by both the teacher's ID AND The maximum length determined from the inner query. Try to take the pieces of your puzzle problems one at a time, then blend together as needed.

Additional option for you in VFP... AS YOU are LEARNING, build the pieces and query them into temporary cursors to be used for the next step. The working example could have also been done as using the original query

INTO CURSOR 
   C_MaxCoursePerTeacher

Then using that as the join such as ...

select
      CMax.ID, ;
      T.Name as TeacherName, ;
      c2.Name as CourseName,;
      c2.Length ;
   from ;
      C_MaxCoursePerTeacher CMax ;
         JOIN Teachers t ;
            on CMax.ID = t.id ;
         JOIN Courses c2 ;
            on CMax.ID = c2.ID ;
            AND CMax.CourseMaxLen = c2.Length

This way, you can get one working query done at a time, know what its purpose if for, then move to the next piece(s) of the puzzle.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top