Reputation: 589
I got some great help over at Returning the first X records in a postgresql query with a unique field with an issue that I'm having and trying to optimize as much as I can for now (though I'm usually not a big fan of front-loading the optimization, this is kind of a unique situation).
Imagine three entities in an app:
User
Post
Instance # An instance is just a reference to a post
The fields look something like this:
User
id
Post
id
user_id
name
Instance
id
user_id
post_id
helped_by_user_id
Requirements:
Return 10 instances where:
EDIT:
I've created an SQLFiddle for this at http://sqlfiddle.com/#!10/7a324/1/0.
For the record, I'm using Ruby 1.9.3, Rails 3.2.13, and Postgresql (Heroku)
Upvotes: 2
Views: 103
Reputation: 589
Just so it's easier to read, with 100% of the credit going to @CraigRinger, the final solution that worked great for me was:
SELECT DISTINCT ON (post_id) *
FROM instances i
WHERE i.user_id <> 3
AND i.helped_by_user_id IS NULL
AND NOT EXISTS (
SELECT 1
FROM instances ii
WHERE ii.post_id = i.post_id
AND ii.helped_by_user_id = 3
)
ORDER BY i.post_id
LIMIT 10;
Upvotes: 0
Reputation: 324821
Right, so you want posts written by somebody other than $user where no "instance" (appears to mean "reply") for $user appears. From this set you wish to select ten distinct posts.
If that's an accurate framing of the problem, this does what you want:
SELECT *
FROM posts p
WHERE p.user_id <> 3
AND NOT EXISTS (
SELECT 1
FROM instances i
WHERE i.post_id = p.id
AND i.helped_by_user_id = 3
)
ORDER BY p.id
LIMIT 10;
Overall, it feels like the issue here is that the problem isn't really framed clearly. Usually, if you can say in clear English what you want from a data set, it's then quite easy to translate it into useful SQL.
Upvotes: 3