tags:

views:

53

answers:

3

Suppose you have two tables:

Musicians

  • musicianID (primary key, int)
  • name (varchar)
  • instrument (varchar)

Gigs

  • GigID (primary key, int)
  • musicianID (foreign key from Musicians)
  • location (varchar)

How would I retrieve the musicianIDs which have not played a gig i.e. that don't have a reference in the Gigs table?

Thanks!

+2  A: 

For example:

SELECT *
FROM Musicians m
WHERE NOT EXISTS (
    SELECT 1
    FROM Gigs g
    WHERE g.musicianID = m.musicianID
)

Here's the (e.g.) MySQL documentation on EXISTS and NOT EXISTS.

martin clayton
+2  A: 
SELECT
   M.*
FROM Musicians M
  LEFT OUTER JOIN Gigs G
      ON G.musicianId = M.musicianID
WHERE G.musicianId IS NULL
George
+4  A: 

This may be more efficient than the query suggested by martin because it doesn't use a subquery:

select musicianID
from musicians m
left join gigs g on g.musicianId = m.musicianID
where g.musicianId is null
ggiroux
yeah, but it does a join. I would check the query analyzer on the specific system to determine that :)
Arthur Thomas
Certainly - I am positive that on mysql this would be more efficient for any non-trivial amount of data - subqueries being a bolted-on feature.
ggiroux
@Arthur Thomas: Joins are always quicker than sub-queries. Most of the time a sub-query will be O(N1*N2) and join will be O(N1+N2) or O(max(N1,N2)) -- it is just like a nested loop.
Hogan
@Hogan: A subquery is like a nested loop when it is a *correlated* subquery, but a simple subquery like `select ID from User where name = 'bobo'` is usually optimized by the compiler to only run once.
RedFilter
@OrbMan: Sure, could be true depending on the implementation -- Not the case here, the where statement in the sub-query used a value in the outer query. No point in talking about edge cases when people are not grasping the basics.
Hogan
thats cool. I just mention that because I did an explain on some sample tables I made up and it came up with the same plan. But of course my dataset was as small as it gets haha.
Arthur Thomas
@Arthur Thomas -- hmmm... have to see the plan... maybe you had a typo in the `WHERE g.musicianID = m.musicianID` line?
Hogan