tags:

views:

41

answers:

3

Hopefully I can ask this without being confusing. I am a photographer and I am having some of our clients rate pictures that we have taken. We have hundreds of pictures in our portfolio that they may be rating. What I want to do is ask our clients to rate pictures again, but only show them the pictures they haven't yet rated. I currently have three tables: one that stores the actual ratings, one that stores the pictures (or location of each picture), and one that stores the information about the rater. I'm using codeigniter for my db management, if that helps at all. What I have so far is this:

"SELECT * FROM ratings LEFT JOIN portfolio ON ratings.portfolioid = portfolio.portfolioid"

This will give me a row for each rating, but won't show me where a rating is missing for a picture. Thanks in advance!

+1  A: 
SELECT * FROM portfolio WHERE NOT EXISTS ( SELECT * FROM ratings where ratings.portfolioid = portfolio.portfolioid )

SELECT * FROM portfolio LEFT JOIN ratings ON portfolio.portfolioid = ratings.portfolioid WHERE ratings.portfolioid IS NULL

Should both give you the ones with no rating.

Don
The LEFT JOIN version is the better way to go (better performance).
nathan
I also commented under the other answer....I believe this will show me only those pictures that haven't been rated at all. What I want is to show the pictures that haven't been rated by a particular person. I'm also recording the email address of the person, but whenever I put (AND email = '[email protected]') it gives an empty result. Any ideas?
Dustin
A: 

I can't test it right now, but would something like this do the job:

SELECT * FROM portfolio LEFT JOIN (
  SELECT portfolioid FROM rating WHERE email = "[email protected]"
) AS rated USING (portfolioid)
WHERE rated.portfolioid IS NULL
ChrisV
I'm getting a db error: Unknown column 'ratings.portfolioid' in 'where clause'...I'm not sure why. I'm pretty sure I didn't spell anything incorrectly. Could this be because of the particular query?
Dustin
You should have WHERE rated.portfolioid IS NULL, not WHERE ratings.portfolioid IS NULL – rated is the name of the temporary table generated by the subquery.
ChrisV
Beautiful!!! That did it (at least I think so). Sorry about the dumb mistake :) Thanks for the help!
Dustin
+1  A: 

@ChrisV - You can avoid the subselect with this version:

SELECT * FROM portfolio p 
LEFT OUTER JOIN rating r ON r.portfolioid = p.portfolioid AND r.email = '[email protected]'
WHERE r.portfolioid IS NULL

That's the beauty of OUTER JOIN with extra conditions. The extra condition gets applied before the join. It will only join portfolios to ratings that match the extra condition (AND r.email = ...), so if a rating doesn't exist, it means that '[email protected]' hasn't rated that portfolio.

nathan
Good one – I had a nagging feeling I was missing a better approach! This will optimise better as well as being simpler.
ChrisV