我需要帮助查询涉及使用以下两个表设置的审阅系统。
reviews ------- id date user_id item_id rating review 1 02-2012 40 456 3 'I like it' 2 03-2012 22 342 1 'I don't like it' 3 04-2012 45 548 0 'I hate it'
reviews_thumbs -------------- review_id user_id like 1 22 1 1 45 -1 2 40 -1 3 22 1
“reviews_thumbs”表用于跟踪评论的upvotes和downvotes,因此评论可以按质量进行评级。在'like'列中,1表示upvote,-1表示downvote。 (评论表中的rating
列是星系,不相关。)
加载评论时,我需要以这样一种方式加入reviews_thumbs表,以便我知道以下详细信息(对于每个单独的评论,它们都会被返回):
1. The total number of upvotes 2. The total number of downvotes 3. Whether the current active user has upvoted or downvoted the review
我使用以下查询完成了此操作,而这个查询并不适合我:
SELECT `reviews`.*, COUNT(upVoteTable.`user_id`) AS upVotes, COUNT(downVoteTable.`user_id`) AS downVotes, COUNT(userUpTable.`user_id`) AS userUp, COUNT(userDownTable.`user_id`) as userDown FROM `reviews` LEFT JOIN `reviews_thumbs` AS upVoteTable ON upVoteTable.`review_id` = `reviews`.`id` AND upVoteTable.`like` = 1 LEFT JOIN `reviews_thumbs` AS downVoteTable ON downVoteTable.`review_id` = `reviews`.`id` AND downVoteTable.`like` = -1 LEFT JOIN `reviews_thumbs` AS userUpTable ON userUpTable.`review_id` = `reviews`.`id` AND userUpTable.`like` = 1 AND userUpTable.`user_id` = :userid LEFT JOIN `reviews_thumbs` AS userDownTable ON userDownTable.`review_id` = `reviews`.`id` AND userDownTable.`like` = -1 AND userDownTable.`user_id` = :userid WHERE `item_id`=:itemid GROUP BY `reviews`.`id` ORDER BY `date` DESC
(并绑定适当的:userid和:itemid。)
因此,此查询完美运行并完成了我需要它。但这是很多加入,我几乎是肯定的,必须有一个更好的方法来做到这一点,但我似乎无法搞清楚。
有人可以指点我如何以更清洁的方式实现这个目标吗?
我尝试过的事情:
我尝试过做一个GROUP_CONCAT,列出一个包含所有用户id和喜欢的字符串,然后运行一个正则表达式来查找用户的id以查看他们是否已经对评论进行了投票,但这也感觉到了真的不干净。
提前感谢您提供的任何帮助。
答案 0 :(得分:1)
您可以将reviews_thumbs修改为更像这样:
reviews_thumbs
--------------
review_id user_id upvote downvote
1 22 1 0
1 45 0 1
2 40 0 1
3 22 1 0
这可以有效地存储重复的信息,但是当你有一个好的目的时,这没关系。你真的有两件事你想知道,这给你一个2列的快速总和(以及对这些结果的快速减法),以准确得到你想要的东西。这可以减少你将reviews_thumbs表查询为2x,一次查询总数,一次查询用户特定操作。
答案 1 :(得分:0)
不确定这是否会提高您的查询效果,但您可以尝试在子选择中进行计数
SELECT `reviews`.*,
(SELECT count(*) FROM reviews_thumbs t WHERE t.review_id =reviews.id AND t.like = 1) AS upVotes
...
FROM reviews
...