Reputation: 1133
I’m working on a PHP voting system and I want to check logged in user voted on posts and display voted if the user have voted. I would like to do it in one single query without using multiple quires. Posts table
+---------+--------+--------+
| post_id | title | c_id |
+---------+--------+--------+
| 1 | post 1 | 2 |
| 2 | post 2 | 3 |
| 3 | post 3 | 2 |
| 4 | post 4 | 1 |
+---------+--------+--------+
MySQL Loop
SELECT *
FROM posts
LEFT
JOIN categories
ON categories.cat_id = posts.c_id
WHERE posts.c_id = categories.cat_id
AND posts. active = 1
ORDER
BY posts.post_id DESC
LIMIT 0, 10
Votes table
+---------+--------+---------+
| vote_id | p_id | u_id |
+---------+--------+---------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 2 | 2 |
| 4 | 4 | 1 |
+---------+--------+---------+
Logged in user = $uid
So if I run query inside the above MySQL loop it work fine
SELECT * FROM votes WHERE u_id = $uid AND p_id= $post_id
Is there a way to combine these two queries?
Upvotes: 2
Views: 174
Reputation: 3008
SELECT *
FROM posts P
LEFT
JOIN categories C
ON C.cat_id = P.c_id
LEFT JOIN (SELECT p_id FROM votes WHERE u_id = $uid) V
ON V.p_id=P.post_id
WHERE P. active = 1
ORDER
BY P.post_id DESC
LIMIT 0, 10 ;
Upvotes: 3
Reputation: 2101
LEFT JOIN
votes table (also no need fo left join categories if you don't want null-joins). If user has voted there will be values in joined columns - nulls will be joined otherwise.
SELECT *
FROM posts AS p
INNER JOIN categories AS c ON c.cat_id = p.c_id
LEFT JOIN votes AS v ON p.post_id = v.p_id AND v.u_id = $uid
WHERE p.active = 1
ORDER BY p.post_id DESC
LIMIT 0, 10
Not voted post will have nulls in vote columns, but since you want only know if user has voted you may limit output data (get only what you need) specifying concrete fields and make voted
column that returns 1/0 values only:
SELECT p.*, c.title, ..., IF(v.vote_id; 1; 0) AS voted
Upvotes: 1
Reputation: 488
You can't select votes as an array in a column but you can actually extract votes and group them. So basically what we'll do is join the two tables partially and maybe sum all the votes
SELECT p.*, c.*, sum(v.Score) FROM posts p LEFT JOIN categories c ON c.cat_id = p.c_id LEFT JOIN votes v ON p.post_id = v.p_id WHERE p.active = 1 AND v.u_id = $uid GROUP BY p.post_id ORDER BY p.post_id DESC LIMIT 0, 10
You can see that I'm summing all the scores in the votes in case there're duplications
Upvotes: 0
Reputation: 7617
You could use a join targeting the common Fields in both the Votes Table and the Posts Table like so:
<?php
$sql = "SELECT * FROM votes AS V LEFT JOIN posts AS P ON V.p_id=P.post_id
WHERE (V.u_id={$uid} AND V.p_id={$post_id}) GROUP BY V.u_id";
Upvotes: 0