Wrox Home  
Search P2P Archive for: Go

  Return to Index  

sql_language thread: Left Outer Join with a previous selection


Message #1 by "Tomŕs Jiménez Lozano" <tomas@v...> on Tue, 4 Dec 2001 19:14:30
David Cameron wrote:
> You can perform this logic in a join but there is (or was for me) a lot 
of
> thinking in trying to get the joins set up and query is slow. Meet you 
new
> best friend, sub queries.
> 
> SELECT t.idteacher, t.age, rt.opinion
> FROM teachers t
>     LEFT OUTER JOIN rt ON
>     t.idteacher=rt.idteacher
> WHERE EXISTS (SELECT NULL
>              FROM rteacherstudent
>              WHERE idstudent='Thomas'
>                  AND idteacher=rt.idteacher)
> 
> Effectively what happens is that the subquery builds a list of teachers 
that
> the student has. You then select the information you need for each of the
> teachers in that list.
> 
> Also you will find a speed gain if you create a temp table and drop the 
list
> of teachers into the temp table, then run the select query on the temp
> table. The reason is that with the current statement the subquery is 
being
> run for each row, but would be run only once if a temp table was used. 
Then
> you would be performing a less expensive query on the temp table for each
> row.

In this case, the query would be more logically structured as:

 SELECT t.idteacher, t.age, rt.opinion
 FROM teachers t
     LEFT OUTER JOIN rteacherstudent rt ON
     t.idteacher=rt.idteacher
 where rt.idstudent = 'Thomas'

rather than using a subquery with EXISTS, since you've joined the tables 
anyway. However, the original poster wanted a way to get either Thomas' 
rating, or NULL, for each teacher. In that case, the logical option is to 
join to a derived table:

 SELECT t.idteacher, t.age, rt.opinion
 FROM teachers t
     LEFT OUTER JOIN (select * from rteacherstudent
                      where idstudent = 'Thomas') rt ON
     t.idteacher=rt.idteacher

This is essentially the same as your suggestion of a temp table, except 
that you don't have to build a temp table, and you're joining instead of 
subquerying it in a WHERE clause.

--Wilson

  Return to Index