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