我的网站上有一个类似Facebook的喜欢/不喜欢系统,我使用以下查询来获取特定帖子的喜欢/不喜欢:

SELECT DISTINCT * FROM posts WHERE cid='$cid' AND pid=".implode(" OR pid=",$pids)." ORDER BY time DESC

$pid是要搜索的post id数组。
zbid是当前访问该页的用户的id。现在,如果该用户已经评分(喜欢/不喜欢),那么应该首先返回post-his结果,然后按time DESC排序结果。
如何修改查询来执行此操作?
如果posts表包含以下数据:
+----+-----+------+-----+--------+------+
|id | cid | zbid | pid |额定值|时间|
+----+-----+------+-----+--------+------+
|1 | 1 | 1 | 1 | 1|
+----+-----+------+-----+--------+------+
|2 | 1 | 2 | 1 |-1 | 4|
+----+-----+------+-----+--------+------+
|3 | 1 | 3 | 2 | 1 | 2|
+----+-----+------+-----+--------+------+
|4 | 2 | 4 | 1 |-1 | 3|
+----+-----+------+-----+--------+------+
|5 | 1 | 5 | 1 | 1 | 8|
+----+-----+------+-----+--------+------+
|6 | 1 | 6 | 1 |-1 | 7|
+----+-----+------+-----+--------+------+
当前的select语句(上面)将返回以下信息(带$pid = array(1);):
+----+-----+------+-----+--------+------+
|id | cid | zbid | pid |额定值|时间|
+----+-----+------+-----+--------+------+
|5 | 1 | 5 | 1 | 1 | 8|
+----+-----+------+-----+--------+------+
|6 | 1 | 6 | 1 |-1 | 7|
+----+-----+------+-----+--------+------+
|2 | 1 | 2 | 1 |-1 | 4|
+----+-----+------+-----+--------+------+
|4 | 2 | 4 | 1 |-1 | 3|
+----+-----+------+-----+--------+------+
|1 | 1 | 1 | 1 | 1|
+----+-----+------+-----+--------+------+
但是,如果zbid=4的人正在访问页面,则应该将结果(如果存在)颠倒到下面的顶部:
+----+-----+------+-----+--------+------+
|id | cid | zbid | pid |额定值|时间|
+----+-----+------+-----+--------+------+
|4 | 2 | 4 | 1 |-1 | 3|
+----+-----+------+-----+--------+------+
|5 | 1 | 5 | 1 | 1 | 8|
+----+-----+------+-----+--------+------+
|6 | 1 | 6 | 1 |-1 | 7|
+----+-----+------+-----+--------+------+
|2 | 1 | 2 | 1 |-1 | 4|
+----+-----+------+-----+--------+------+
|1 | 1 | 1 | 1 | 1|
+----+-----+------+-----+--------+------+
变量$zbid设置为访问页面的用户的zbid

最佳答案

这是一个相当粗略的解决方案,我可以用你提供的信息:
解决方案1-便携式方式

-- This query will return User's posts and give it a higher priority in ordering, via post_order field
SELECT
  posts.*
  ,0 as post_order
FROM posts
WHERE
  (cid='$cid' AND pid=".implode(" OR pid=",$pids).") AND
  (zbid = $user_zbid)

UNION ALL

-- This query will return everything BUT User's posts and give it a lower priority in ordering
SELECT
  posts.*
  ,1 as post_order
FROM posts
WHERE
  (cid='$cid' AND pid=".implode(" OR pid=",$pids).") AND
  (zbid <> $user_zbid)
ORDER BY
  post_order -- This clause will put User's posts before the others
  ,time DESC

解决方案2-更有效的方式(建议的学分cbranch
SELECT
  posts.*
  ,IF(zbid = $user_zbid, 0, 1) as post_order
FROM posts
WHERE
  (cid='$cid' AND pid=".implode(" OR pid=",$pids).")
ORDER BY
  post_order -- This clause will put User's posts before the others
  ,time DESC

笔记
-正如您可能已经注意到的,我从SELECT中删除了DISTINCT,因为我看不出它们的原因。因为您只是从一个表中提取数据,所以不应该有重复的。显然,您仍然可以将它们添加回去,但请记住,除非确实需要,否则不要使用此类子句。
-第二个查询将非常昂贵,因为它使用“不等于”子句。这意味着它不会使用索引,也不适合大量数据。如果您必须处理一个大表,这个解决方案将不得不检讨。

09-17 01:15