简体   繁体   中英

PHP voting system check votes

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?

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 ;

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

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";

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM