Search code examples
sqljoininner-join

SQL: How to dynamically calculate a value from a separate table?


I'm building a Hacker News-style page, and I'm trying to get a list of posts from the database to display on the page, including data as to whether or not the current user has voted on a particular post.

I'm trying to query a list of posts (from the posts table), and I want to perform a join on the votes table (post.id on votes.postId) to see if a given post has been voted on by the current user, and return something like userHasVoted for each post that comes back, calculated on the fly.

I've been trying to make this happen, but only seem to return the posts the user has voted for.

How can I query the DB to show every post and whether or not it was voted on by a given user?

Here is my votes table:

+----+--------+--------+-------+
| id | userId | postId | value |
+----+--------+--------+-------+
|  1 |      1 |      1 |     1 |
|  2 |      2 |      1 |     1 |
|  3 |      4 |      3 |     1 |
|  4 |      1 |      5 |     0 |
|  5 |      3 |      2 |     1 |
|  6 |      4 |      8 |     1 |
|  7 |      1 |      8 |     1 |
|  8 |      4 |      9 |     1 |
|  9 |      1 |      9 |     1 |
+----+--------+--------+-------+

And here's my posts table (leaving out title, content, link, etc):

+----+---------------+--------+
| id | publishStatus |authorId|
+----+---------------+--------+
|  1 | PUBLIC        |      1 |
|  2 | PUBLIC        |      2 |
|  3 | PUBLIC        |      3 |
|  4 | PUBLIC        |      4 |
|  5 | PUBLIC        |      2 |
|  6 | PUBLIC        |      1 |
|  7 | PUBLIC        |      1 |
|  8 | PUBLIC        |      1 |
|  9 | PUBLIC        |      1 |
+----+---------------+--------+

Solution

  • The following is an example where you could get Yes or No instead of 1 or 0

    SELECT DISTINCT p.*, CASE 
            WHEN v.value = 0
                THEN 'No'
            ELSE 'Yes'
            END userHasVoted
    FROM posts p
    INNER JOIN votes v ON p.id = v.postid
    

    enter image description here